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

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

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

Другие каналы: @tproger_channels
Download Telegram
Gradle 9.5.1 в одноразовом CI: сокращаем запуск сборки

В свежем CI-контейнере нет состояния предыдущего запуска, поэтому Gradle снова получает дистрибутив и готовит служебные файлы. Для Java-проекта это лишнее время до выполнения задач сборки.

В разборе запуска Gradle проверяют три приёма: использовать дистрибутив -bin вместо -all, восстанавливать каталоги Wrapper и заранее готовить generated-gradle-jars вместе с jars-9. Версии образа и Wrapper нужно согласовать, а после обновления Gradle пересобрать подготовленный образ и проверить пути кэша.

Результаты служат ориентиром: небольшой Spring Boot-проект собирали в чистом Docker-окружении по пять раз, базовый прогон занял 31,7 секунды. Повторите замеры на своей кодовой базе: в крупной сборке больше времени могут отнимать зависимости, конфигурация или выполнение задач.
Как проверить отправку Kafka-сообщения в Spring Boot без Docker

В интеграционном тесте с Embedded Kafka настоящий брокер запускается внутри тестового процесса. Аннотация @EmbeddedKafka создаёт топик greetings, поэтому внешняя Kafka и Docker не нужны.

KafkaTemplate публикует сообщение, а отдельный KafkaConsumer получает запись через KafkaTestUtils.getSingleRecord. Перед отправкой тест считывает сообщения, созданные ApplicationRunner при запуске, чтобы проверка не забрала старую запись.

Тест подтверждает доставку от продюсера до брокера и обратно к потребителю, но не результат работы метода с @KafkaListener. Эффект обработчика стоит проверять отдельно: так транспортная интеграция и бизнес-логика не маскируют ошибки друг друга.
Java 25 и Micronaut: упрощаем точку входа через compact source file

В Java 25 механизм compact source files финализирован в JEP 512. Он позволяет запускать программу без явного объявления класса и метода public static void main. Для Micronaut точка входа сокращается до импорта, void main() и вызова Micronaut.run().

Меняется и Gradle: вместо полного имени com.example.Application в mainClass достаточно Application. Неявный класс получает имя файла, поэтому Application.java и значение mainClass должны совпадать точно.

Для существующего проекта это локальное упрощение стартового кода, но структуру исходников придётся проверить: файл без объявления пакета лучше держать в корне src/main/java, иначе IDE и инкрементальная компиляция могут работать хуже. В примере с конфигурацией Gradle показаны оба варианта точки входа.
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.