Всем привет! ? ? ? ? Мы — Java-разработчики Т-Банка: Андрей, Арсений, Константин и Константин. Собираем интересные новости, статьи, туториалы и другие материалы из мира Java-разработки и делимся этим со всем сообществом.
В этом выпуске мы пройдемся по JEP, которые попадут в Java 24. Взглянем на новые релизы: IntelliJ IDEA 2024.3, Spring Framework 6.2 и Spring Boot 3.4, а еще Armeria 1.31.0 и Kora 1.1.16. Посмотрим новый алгоритм сбора мусора Mark-Scavenge. Узнаем больше о точках отказа в хайлоад-системах и LLVM. А еще разберемся, как ускоряли time-to-code в IntelliJ IDEA, какие тонкости есть в Hibernate и во многом другом ?
Свежие JEP
В Java 24 было направлено много JEP. О некоторых мы писали, но для полноты картины решили добавить.
Вот они слева направо:
404: Generational Shenandoah (Experimental)
JEP 404: Shenandoah c поколениями — экспериментальный режим работы сборщика мусора Shenandoah для повышения пропускной способности и устойчивости к скачкам нагрузки. Цель — сократить объем занимаемой памяти и использование процессора, уменьшить риск неполных коллекций и поддерживать высокую производительность.
450: Compact Object Headers (Experimental)
Уменьшение заголовков объектов в HotSpot JVM. Сейчас от может составлять от 96 до 128 бит. Этот джек снижает его до 64 бит на 64-разрядных архитектурах. Цель — уменьшить размер кучи, повысить плотность развертывания и увеличить локальность данных. По словам авторов, эта экспериментальная функция окажет широкое влияние на реальные приложения, что не может не радовать. Ключи для включения: -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders.
472: Prepare to Restrict the Use of JNI
Цель — сохранить статус JNI как стандартного способа взаимодействия с машинным кодом и подготовить экосистему Java к будущему выпуску. Разработчики приложений должны явно разрешить использование JNI и FFM API при запуске. При этом целью будет не осуждение JNI или удаление JNI с платформы Java, а обеспечение целостности по умолчанию.
475: Late Barrier Expansion for G1
JEP 475 предлагает упростить реализацию барьеров G1 для C2 JIT. Цель — сократить время выполнения C2 и сделать барьеры понятными для разработчиков. Раннее расширение барьеров увеличивало накладные расходы C2 на 10—20%. JEP точно понравится людям, которые любят изучать устройство сборщиков мусора, так как новый подход очень подробно описан.
478: Key Derivation Function API (Preview)
Внедрение API для функций получения ключей (KDFs) в Java. API KDF предназначен для использования алгоритмов KDF, таких как HKDF и Argon2. KDF используются для создания криптографически надежного материала ключей. Цель — поддержка постквантовой криптографии и гибридного шифрования с открытым ключом (HPKE).
А вообще, заметна тенденция к развитию квантовых алгоритмов в JDK, дальше в JEP вы это увидите. Интересно, когда мы будем создавать на Java код для квантовых компьютеров?
479: Remove the Windows 32-bit x86 Port
Удаление 32-разрядного порта Windows 86 из JDK 21.
Цель — удалить все пути к коду, применимые только к 32-разрядной версии Windows x86. Нужно это, чтобы прекратить тестирование и разработку на 32-разрядной платформе Windows x86.
483: Ahead-of-Time Class Loading & Linking
Заблаговременная загрузка и привязка классов для сокращения времени запуска Java-приложений. Цель — сократить время запуска, не требуя изменений в коде приложений, библиотек или фреймворков. Расширение JVM HotSpot для поддержки заблаговременного кэша классов. Тренировочный запуск фиксирует конфигурацию приложения для использования в последующих тестовых и производственных запусках.
Арсений
Звучит мегакруто. Я думаю, многие читатели грели свой код и понимают, как это может упростить жизнь.
484: Class-File API
API Class-File предлагает стандартный API для анализа, генерации и преобразования файлов классов Java. Изначально API предложили в JDK 22 и доработали в JDK 23. Цель — предоставить API для обработки файлов классов, отслеживая формат файла, определенный спецификацией виртуальной машины Java.
485: Stream Gatherers
Усовершенствование Stream API для поддержки пользовательских промежуточных операций. Цель — сделать потоковые конвейеры более гибкими и выразительными. Stream API предоставляет богатый, но фиксированный набор промежуточных и конечных операций. Встроенные промежуточные операции не всегда подходят для решения сложных задач. Предлагается добавить пользовательские промежуточные операции для управления потоками бесконечного размера.
Арсений
Математики есть? ? Мне кажется, очень зайдет тем, кто проводит на Java много потоковых расчетов.
486: Permanently Disable the Security Manager
Окончательное отключение диспетчера безопасности. Диспетчер безопасности не основное средство защиты клиентского Java-кода и редко используется для защиты серверного кода. Цель — удалить возможность включать диспетчер безопасности при запуске Java runtime и лишить возможности устанавливать диспетчер безопасности во время работы приложения.
487: Scoped Values (Fourth Preview)
Эх, все еще превью. Значения с областью видимости, которые позволяют методу использовать неизменяемые данные совместно как с вызывающими его методами в рамках потока, так и с дочерними потоками. Значения с областью видимости проще в использовании, чем локальные переменные потока. Они также требуют меньше места и времени, особенно при использовании вместе с виртуальными потоками (JEP 444) и структурированным параллелизмом (JEP 480).
488: Primitive Types in Patterns, instanceof, and switch (Second Preview)
JEP 488 предлагает разрешить использование примитивных типов в шаблонах, instanceof-ах и switch-ах. Цель — сделать язык Java более единообразным и выразительным. Ведь как мы знаем, Pattern Matching — это круто и модно.
489: Vector API (Ninth Incubator)
Цыпленок, который остается в инкубаторе в рекордный раз.
Vector API предлагает понятный и лаконичный API для выражения векторных операций. API не зависит от платформы и может быть реализован на нескольких архитектурах. Vector API обеспечивает надежную компиляцию векторных операций во время выполнения и высокую производительность на ×64 и AArch64.
Напоминаем, что JEP ждет Project Valhalla, а пока остается мемом.
490: ZGC: Remove the Non-Generational Mode
ZGC всегда будет работать в Generational-режиме, а старый режим вырежут. Цель — сократить затраты на техническое обслуживание, поддерживая два режима ZGC.
491: Synchronize Virtual Threads without Pinning
Синхронизация виртуальных потоков без закрепления улучшает масштабируемость Java-кода. Виртуальные потоки блокируются в синхронизированных методах и инструкциях, освобождая потоки платформы для других виртуальных потоков. Цель — разрешить существующим библиотекам Java хорошо масштабироваться с виртуальными потоками без изменения кода. Виртуальные потоки сокращают затраты на разработку и обслуживание высокопроизводительных параллельных приложений.
Арсений
Да и вообще, виртуальные потоки — очень крутой инструмент, и мне нравится, что они перестанут наконец спотыкаться на synchronized в следующей LTS.
492: Flexible Constructor Bodies (Third Preview)
В конструкторах Java разрешат инструкции перед явным вызовом конструктора (super() или this()). Операторы не смогут ссылаться на создаваемый экземпляр, но смогут инициализировать его поля. Инициализация полей перед вызовом другого конструктора делает класс более надежным при переопределении методов. Цель — переосмыслить роль конструкторов в процессе инициализации объекта и упростить написание и поддержку кода. Уже есть идеи, какие лютые красивые конструкторы вы напишете? Поделитесь в комментариях!
493: Linking Run-Time Images without JMODs
Уменьшение размера JDK на 25% с использованием инструмента jlink для создания пользовательских образов.
Цель — разрешить связывание образа во время выполнения из модулей, независимо от их типа.
Мотивация — уменьшение размера JDK важно в облачных средах для повышения эффективности операций.
494: Module Import Declarations (Second Preview)
JEP 494 предлагает функцию импорта всех пакетов, экспортируемых модулем. Это упрощает повторное использование модульных библиотек и избавляет от необходимости импортировать код из модуля. Цель — упростить повторное использование модульных библиотек и избежать шума от многочисленных объявлений типа «импорт по требованию».
Арсений
Мне кажется, это прикольно: можно будет смотреть на Java-класс и видеть, какие пакеты берутся не из модулей, проще контролировать зависимости.
495: Simple Source Files and Instance Main Methods (Fourth Preview)
JEP предлагает упростить создание Java-программ для новичков и опытных разработчиков. Цель — помочь новичкам плавно перейти к программированию на Java и облегчить обучение. Предлагается упростить написание небольших программ без изменения структуры языка Java. Вводятся новые методы для работы с консолью и взаимодействия с пользователем. Автоматически импортируются полезные методы и классы для небольших программ.
Арсений
Каждый раз думал: «Как же жалко людей которые будут учиться программировать на облегченной версии Java и сталкиваться на работе с legacy на JDK8» ?
496: Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism
Квантово-стойкий модуль — механизм инкапсуляции ключей на основе решетки. Цель — обеспечить реализацию ML-KEM для API-интерфейсов с поддержкой наборов параметров ML-KEM-512, ML-KEM-768 и ML-KEM-1024.
Мотивация — область применения квантовых вычислений развивается, и ML-KEM обеспечивает защиту от атак на квантовые компьютеры.
497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm
Квантово-стойкий модуль-алгоритм цифровой подписи на основе решетки (ML-DSA) для повышения безопасности Java-приложений. ML-DSA разработан для защиты от будущих атак на квантовые вычисления и стандартизирован в FIPS 204. Цель — обеспечить реализацию ML-DSA с API-интерфейсами для поддержки наборов параметров ML-DSA-44, ML-DSA-65 и ML-DSA-87.
498: Warn upon Use of Memory-Access Methods in sun.misc.Unsafe
Основная задача — начать предупреждать разработчиков об использовании Unsafe, так как он не поддерживается и уходит в небытие. В качестве замены Unsafe можно использовать JEP 454. Ожидается, что предупреждать будут как о прямом использовании Unsafe, так и о неявном — через методы библиотек. В последнем релизе Java выходил JEP 471, в котором Unsafe был помечен для удаления.
499: Structured Concurrency (Fourth Preview)
JEP 499 предлагает API для структурированного параллелизма в Java. Структурированный параллелизм упрощает параллельное программирование и повышает надежность и наблюдаемость кода. API основан на принципе, по которому все подзадачи возвращаются в одно и то же место — блок кода задачи. Подзадачи работают от имени задачи и отслеживаются на предмет сбоев. Структурированный параллелизм подходит для виртуальных потоков и обработки тысяч или миллионов запросов.
501: Deprecate the 32-bit x86 Port for Removal
Рекомендуется отказаться от использования 32-разрядного порта ×86. Это приведет к отмене 32-разрядного порта ×86 для Linux и всех остальных 32-разрядных портов ×86. Цель — освободить новые функции от необходимости реализации 32-разрядных резервных версий ×86. Отказ от использования порта позволит разработчикам OpenJDK ускорить разработку новых функций. А их надо жалеть ?
Новые релизы
Полный список фич можете посмотреть на Jetbrains, а мы расскажем про три основные фичи:
Окно, отображающее структуру кода, помимо физической теперь отображает также логическую структуру. Например, для контроллера будет отображаться набор ендпоинтов. Подробнее об этой фиче можно прочитать в блоге. Вообще, она нам что-то напоминает…
AI-ассистент. Теперь промты можно писать прямо в редакторе кода, а к чату можно подключить другие модельки, например ChatGPT, Gemini или даже локальную модель, развернутую на вашем компьютере. Интересно, куда еще добавят AI?
Kubernetes. Добавили режим удаленного дебага, в котором вы буквально превращаете свою машину в виртуальную часть кластера. Так кубер будет работать с инстансом приложения, поднятым на виртуальной машине так, как будто оно находится в кластере. Кроме того, добавили удобную агрегацию и поиск событий из разных кластеров.
Spring Framework 6.2 and Spring Boot 3.4 Improve Containers, Actuators ahead of New 2025 Generations рассказывает о нововведениях Spring Framework 6.2 и Spring boot 3.4. Из интересного: теперь Graceful Shutdown включен по дефолту, структурированное логирование в машиночитаемом формате добавлено из коробки, а еще добавлена возможность указывать аргументы командной строки для интеграции Spring с Docker-compose.
В конце статьи есть небольшая сессия c Juergen Hoeller b Sébastien Deleuze, в которой они отвечают на вопросы о недавно анонсированных Spring Framework 7 и Spring Boot 4. Например, о том, почему шестое поколение спринга оказалось таким коротким, а также о том, каких фич ожидать от седьмой мажорной версии.
Armeria 1.31.0
https://armeria.dev/release-notes/1.31.0
Фреймфорк для написания микросевисов, поддерживает REST, gRPC, Thrift, статические файлы, и все это на одном порту внутри одного приложения. Для gRPC есть поддержка сервиса документации наподобие OpenAPI для REST. А еще можно использовать Armeria для Load-balancing и как Service-discovery.
Динамическая конфигурация TLS. Теперь можно обновлять настройки TLS без перезапуска вашего клиента или сервера.
Nacos Service Discovery. Load-balancing на клиентской стороне с помощью Nacos.
Возможность получить исходный путь запроса при помощи ServiceRequestContext.
Больше статических factory-методов для ResponseEntity.
Поддержка таймаутов для HttpRequest и HttpResponse. А еще фиксы, обновления зависимостей и улучшения.
Kora 1.1.16
https://kora-projects.github.io/kora-docs/ru/changelog/changelog/#1116
Производительный и эффективный фреймворк общего назначения для написания серверных Java/Kotlin-приложений, поддерживающий HTTP, gRPC, Kafka, репозитории к базам данных, генерацию из OpenAPI, планировщики и многое другое.
Вышло сразу несколько версий, вплоть до 1.1.16. В этих версиях из крупного:
Добавили и исправили поддержку специального типа JsonNullable для определения наличия или отсутствия полей в JSON-формате.
Добавили OpenAPI-поддержку в Camunda REST и его телеметрию.
Исправили метрики HTTP-клиента в случае ошибок по OpenTelemetry-стандарту.
Добавили возможность создавать расширенный граф зависимостей, что может пригодиться при тестировании компонент.
Исправили неточности работы трассировки и телеметрии в HTTP-клиенте
Добавили различные улучшения по штатному завершению планировщиков и других модулей.
Главные новости
Mark-Scavenge: Waiting for Trash to Take Itself Out — новый алгоритм сбора мусора. Mark-Scavenge разработан в рамках сотрудничества Oracle и Университета Уппсалы. Новый алгоритм Mark-Scavenge предлагает задержку эвакуации до следующего цикла сбора мусора для сокращения потерь времени. На бенчмарках (DaCapo, SPECjbb2015) Mark-Scavenge показал до 91% уменьшения перемещений ненужных объектов и улучшение производительности:
На загруженных системах уменьшение задержек на 20% в 99-м, 99,9-м и 99,99-м перцентилях.
Рост пропускной способности (max-jOPS) до 8%.
Ускорение критических операций (critical-jOPS) на 2—4%.
Подробнее про новый алгоритм можно прочитать в статье.
Интересные видео
Николай буквально на пальцах разъясняет, какую проблему решает JEP. Что такое пиннинг виртуальных тредов, почему он негативно влияет на производительность и при каких условиях возникает.
По сути, доклад о траблшутинге хайлоад-систем. Рассматриваются три категории точек отказа: память, БД и TCP. Разбираются конкретные случаи сбоев: чем вызван сбой, как его диагностировать и как исправить. Очень практичный доклад.
На самом деле Java тут особо ни при чем ? Это верхнеуровневый обзор LLVM — набора компонент для создания компиляторов и тулчейнов. Компиляторы для C, C++, Rust, Swift и многих других написаны с использованием LLVM. Также Kotlin/Native построен на основе LLVM. Интересный доклад для общего развития.
Полезные статьи
JDK 23: Module Design Pattern with JEP-476. О модульности в Java и использовании модульных импортов, которые были добавлены в JDK 23 в статусе preview.
Efficiently Adding to Persistent Collections — In Relation To. О том, как в Hibernate эффективно добавлять элементы в коллекции, при этом провоцируя минимальное число запросов в базу данных.
Java 24 to Reduce Object Header Size and Save Memory. Рассказывает о JEP 450: Compact Object Headers, которая уже интегрирована в JDK 24 в статусе Experimental и доступна для включения. Цель этого JEP — уменьшить размер хедеров объектов в HotSpot JVM до 64 бит, что также уменьшит размер объектов, улучшит локальность данных и уменьшит нагрузку на GC. Тестирование в Amazon показало увеличение пропускной способности приложений, а на некоторых нагрузках утилизация CPU уменьшилась на 30%.
Java Evolves to Tackle Virtual Threads Pinning with JEP 491. Рассказывает о JEP, который призван решить проблему с пиннигом виртуальных потоков при использовании Synchronized в Java. Вносятся изменения в планировщик JVM, позволяя заблокированным виртуальным потокам отсоединяться от платформенных потоков, освобождая их для других задач. Так виртуальные потоки смогут взаимодействовать с мониторами, не возлагая это на несущий платформенный поток.
Avoid Using Set for Bidirectional JPA OneToMany Collections. Небольшая статья от Vlad Mihalcea, посвященная использованию Set для двунаправленных OneToMany-коллекций. В статье описаны проблемы с производительностью, с которыми можно столкнуться, если определять метод hashCode сущности как getClass().hashCode(). Так как в таком случае мы будем иметь только один Bucket в Set, в результате чего при добавлении нового элемента всегда будем проходиться по всем элементам множества.
YYYY? yyyy! Хорошая статья про неожиданное поведение в форматах дат. YYYY совсем не эквивалентно yyyy. Y — это обозначение недели года (week year), и в некоторых случая формат даты dd-MM-YYYY может увести дату на год вперед или на год назад.
Faster Time-to-Code in IntelliJ IDEA. За последний год в Release Notes к IntelliJ IDEA постоянно появлялся пункт об ускорении индексирования. И действительно, время с момента открытия проекта в среде разработки и до начала работы с кодом (time-to-code) заметно сократилось. В статье разработчики рассказывают, какие приемы они использовали, чтобы этого добиться. Пришлось фактически пересмотреть подход к индексации, чтобы появилась возможность разбить ее на несколько этапов, часть из которых можно выполнить раньше, а другие запустить фоном, когда пользователь уже начал работать с кодом.
Константин
Можно смело сказать, что из подобных статей можно вынести много хороших… Идей ? (Простите, не удержался)
Любопытные подкасты
Выпуск интересен как минимум историей распила PHP-монолита на джавовые микросервисы ? А еще любопытно про опыт работы на аутстафе в компании «Кроссовер». Подход к отбору персонала, требованиям к работе и трекингу времени разработчика поистине удивляет. Затронуты темы скриптинга в Redis (и почему пришлось писать свою реализацию дробных чисел), выбор между Spring и Micronaut, а еще различия между уровнями инженеров.
Спойлер: к концу видео — революция ? Но говорили на самом деле не об этом. Обсуждали, кто как использует Spring в работе. Почему Spring захватил рынок? Чего, возможно, Spring не достает. А еще коснулись внутрянки разработки и контрибьютинга. Получился очень приятный и чиловый подкаст. Надеемся, ребята продолжат ?
Просто интересное
From Code to Clarity With the Redesigned Structure Tool Window. В блоге JetBrains вышла статья про то, как появилось новое окно структуры и как этому поспособствовал AI. Обновленное окно структуры возникло вместе с новым обновлением Intellij IDEA, про которое мы писали выше.
Спасибо, что читаете! Ждем обратной связи в комментариях. Благодарим @rudikone и @alexander-shustanov за присланные материалы. Увидимся через месяц ?
Присылайте материалы, если встретили что-то интересное, — опубликуем в следующем выпуске!
aleksandy
Чё вдруг?
SimSonic
Поддерживаю вопрос, ведь только каждый 4й должен быть LTS...