Чашечка Java
8.37K subscribers
3.93K photos
13 videos
56 files
6.39K links
Лучшие материалы по Java на русском и английском

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels
Download Telegram
Spring Boot 4: как выбрать режим RestTestClient для проверки REST API

Новый RestTestClient позволяет сохранить один способ вызова API и менять охват теста. Клиент привязывается к контроллеру для модульного теста, к MockMvc для проверки валидации и Spring Security, к WebApplicationContext для интеграционного теста либо к запущенному серверу для сквозной проверки по HTTP.

При привязке к контроллеру Spring-контекст не поднимается: зависимости нужно создать или подменить самостоятельно, а валидация бинов и безопасность не проверяются. В примере @AuthenticationPrincipal получает объект с полями null, если не зарегистрировать собственный обработчик аргумента. Это ограничение данного режима и конфигурации теста.

Разбор четырёх режимов RestTestClient показывает настройку клиента и проверки ответа API. Для подключения нужен тестовый модуль spring-boot-starter-webmvc-test.
Как убрать временные MemorySegment при доступе к нативной памяти в Java

В горячем цикле обёртка MemorySegment для каждого нативного адреса создаёт короткоживущие объекты и нагружает GC. Разбор арифметики указателей через FFM API показывает другой путь: один глобальный сегмент начинается с адреса 0 и расширяется через reinterpret до Long.MAX_VALUE.

VarHandle, построенный из описания структуры, получает этот сегмент как базу, а числовой адрес как смещение. Новая обёртка на каждом проходе не нужна. В авторском JMH-тесте такой вариант дал примерно 21 млн против 1,49 млн операций в миллисекунду.

Цена ускорения: глобальный сегмент не проверит, существует ли память по адресу и не была ли она освобождена. Для горячего участка сначала измерьте аллокации и производительность собственным JMH-тестом, а время жизни памяти контролируйте отдельно.
👍1👏1
Spring Boot 3.5 и 4: подключаем Fory JSON к MVC и WebFlux

Spring Fory 1.1.0 требует Java 17 или новее. Для Boot 4 предназначен fory-json-spring-boot-starter, для Boot 3.5 — fory-json-spring-boot3-starter. Стартер выбирает интеграцию для MVC или WebFlux, а контроллеры сохраняют привычные @RequestBody, Mono и Flux.

При миграции настройки придётся перенести явно: аннотации Jackson и параметры spring.jackson.* не управляют Fory. Стоит отдельно проверить имена полей и весь JSON-контракт. Ограничение входных данных в MVC относится ко всему телу запроса, а при потоковом NDJSON в WebFlux — к каждому значению в Flux.

Руководство по интеграции показывает API заказов, настройку преобразования JSON и вариант без Spring Boot. Бенчмарки сериализации не гарантируют такой же прирост HTTP-производительности: результат нужно измерять на своём приложении.
✍1
JDK 25: как передавать контекст запроса через ScopedValue

В JDK 25 ScopedValue стал постоянным API для идентификаторов запросов, данных пользователя и трассировки. Значение привязывается через where(...).run(...), читается через get() во всей цепочке вызовов и автоматически исчезает после выхода из блока. Это убирает сквозные параметры и ручной ThreadLocal.remove().

Во вложенной области значение можно временно перепривязать. После её завершения внешняя привязка восстановится, поэтому время жизни контекста видно прямо в коде.

Практический пример с RequestContext показывает проверку через isBound() до и после блока. Для миграции ScopedValue подходит читаемому контексту с ограниченным временем жизни. ThreadLocal остаётся для изменяемого состояния потока, прежних версий Java и совместимости с существующими API.
JDK 26: когда автовекторизации JIT мало и нужен Vector API

JIT превращает циклы Java в SIMD-инструкции, обрабатывающие несколько чисел за раз. На JDK 26.0.2.1 и Apple M4 Max суммирование миллиона элементов ускорилось примерно вдвое. Вклад оптимизации можно проверить JMH-прогоном с -XX:-UseSuperWord.

Vector API с одним аккумулятором дал те же 113 мкс на операцию, а четыре независимых сократили время до 35 мкс: процессору не пришлось ждать предыдущее сложение.

Сравнение JMH-бенчмарков показывает цену ускорения: Vector API остаётся инкубационным, код усложняется, а выигрыш зависит от CPU. Бенчмарк стоит прогнать на production-сервере.
Как защитить REST API в Spring Boot от несовместимых изменений

В Spring Boot обновление Jackson, смена конфигурации или новая функция могут незаметно нарушить договорённости с клиентами REST API. Контрактные тесты фиксируют ожидаемые запросы и ответы, чтобы поймать расхождение до развёртывания.

Для проверки со стороны провайдера OpenAPI-Diff сравнивает текущую спецификацию со снимком. Метод isCompatible(), в отличие от строгого isUnchanged(), не отклоняет совместимое добавление новых эндпоинтов.

Spring Cloud Contract хранит контракты в YAML, а Maven-плагин генерирует проверочные тесты и WireMock-заглушки для клиентов. Если команда контролирует потребителей API, можно передать им ведение контракта через Pact. Практический разбор трёх подходов помогает выбрать схему и настроить проверки совместимости.
👍1😁1👌1
DAGP 3.5.0 проверяет бинарную совместимость дубликатов классов в Gradle

Если два JAR содержат класс с одинаковым полным именем, JVM загрузит первый найденный в пути классов. Поэтому порядок зависимостей может решить, какая реализация попадёт в работу. На этом же поведении строятся атаки Maven-Hijack.

Dependency Analysis Gradle Plugin запускает проверку через buildHealth. При обнаружении дубликатов DAGP 3.5.0 сравнивает поля и методы классов, включая типы, параметры и модификаторы. Несовместимые сигнатуры помогают найти конфликт версий, ошибочную перепаковку библиотеки или подозрительную подмену класса.

Разбор проверки Gradle-сборки предлагает предупреждать о дубликатах либо останавливать сборку. Ограничение остаётся: вредоносная реализация с прежними сигнатурами пройдёт такую проверку, поэтому DAGP служит ранним сигналом, а не полной защитой.
Spring Boot 4: настраиваем экспорт логов, метрик и трассировок через OpenTelemetry

В Spring Boot 4 появился собственный OpenTelemetry starter. Spring рекомендует его вместо Java-агента и стороннего starter с альфа-зависимостями.

Для логов нужны Logback appender, logback-spring.xml и вызов install(). В 4.0.0 экспорт без Actuator не работал, обе ошибки исправили в 4.0.1.

Метрики потребуют Micrometer и дополнительных bean-компонентов, для трассировок достаточно адреса экспорта. Полная схема настройки включает Docker Compose с Grafana LGTM. Проверьте адрес логов: нужен /v1/logs, не /v1/traces.
Как подтвердить взаимную блокировку по дампу потоков Java

Если JVM перестала выполнять работу, снимите несколько дампов с интервалом в несколько секунд: jcmd <pid> Thread.print -l или jstack -l <pid>.

Найдите потоки в состоянии BLOCKED. Сопоставьте монитор после waiting to lock с потоком, который держит его после locked. Если цепочка вернулась к первому потоку, взаимная блокировка подтверждена.

WAITING и TIMED_WAITING сами по себе нормальны. Практический разбор дампов показывает, как сверить стеки с метриками. Исправлять нужно порядок захвата блокировок: увеличение пула цикл не разорвёт.
🔥1😁1
Как StructuredTaskScope в JDK 27 отменяет лишнюю работу при сбое

Два независимых вызова к сервисам последовательно занимают около двух секунд. Виртуальные потоки с Future сокращают успешный запуск примерно до секунды, но при сбое одного вызова через 200 мс второй продолжает работу. Закрытие ExecutorService ждёт его завершения, хотя результат уже не нужен.

StructuredTaskScope объединяет подзадачи: ошибка одной прерывает соседнюю, а join() сообщает о сбое всей группы. В примере метод возвращается примерно через 200 мс вместо полной секунды.

Сравнение трёх реализаций учитывает седьмую предварительную версию API в JDK 27 и проверяемое исключение ExecutionException. Для запуска нужен --enable-preview. Ограничение сохраняется: задача должна реагировать на прерывание, а закрытие области ждёт завершения всех подзадач.
Как настроить MFA в Spring Security 7 для приложения и отдельных эндпоинтов

Spring Security 7, доступный со Spring Boot 4, добавил FactorGrantedAuthority. После входа по паролю пользователь получает FACTOR_PASSWORD, а после одноразового токена из письма — FACTOR_OTT. Доступ открывается, когда собраны все обязательные факторы.

Для MFA во всём приложении аннотация @EnableMultiFactorAuthentication связывает фильтры входа и создаёт проверку требуемых факторов. Стандартная форма не умеет задавать их порядок, поэтому для последовательного сценария понадобятся собственные страницы.

Чтобы усилить только /admin/**, аннотации передают пустой список факторов, а отдельный AuthorizationManagerFactory назначают этому маршруту. Остальные запросы сохраняют однофакторную проверку. Конфигурация обоих вариантов приведена с кодом.