Новая LTS Java.
Я о Java 25.
Вышла не вчера, поэтому также вышла и хорошая статья с обзором нововведений https://habr.com/ru/companies/T1Holding/articles/946778/.
Там даже табличка включения новых фич от 21 до 25 версии есть. И примеры кода - было\стало.
И от меня как всегда пару комментариев)
Для начала бросаются в глаза две фичи со "странным" названием Quantum-Resistant ...
Почему бросаются - квантовые компьютеры ожидаются в промышленном использовании в течение 10+ лет, а устойчивые к взлому квантовым компьютером алгоритмы в Java появились уже сейчас.
С - стратегия.
Б - банковское ПО)
Три фичи со словами Ahead-of-Time, главная из них - Ahead-of-Time Class Loading & Linking.
Это дальнейшее развитие темы CDS https://t.me/javaKotlinDevOps/316
Т.е. ускорение старта приложения.
Если CDS убирает этап верификации классов сохраняя в архиве уже проверенные классы,
то Ahead-of-Time Class Loading & Linking как следует из названия сохраняет всю необходимую для работы с классами информацию. Так сказать в распакованном виде, поэтому ее сразу можно грузить в Metaspace.
Одно но: набор классов у всех разный, поэтому нужно запустить приложение в тестовом режиме и собрать данные по актуальным классам, которые и будут сохранены в архиве.
Заодно сохраняется и статистика их использования (Ahead-of-Time Method Profiling), что позволяет при старте JVM сразу запустить компиляцию часто используемых методов.
Последняя фича - это offline Profile-Guided Optimization https://t.me/javaKotlinDevOps/315, которая ранее была killer feature коммерческих JVM: Azul ReadyNow и GraalVM Enterprise Native Image.
Итоговое ускорение загрузки: 42% vs 33% у CDS https://www.happycoders.eu/java/ahead-of-time-class-loading-and-linking/
Есть еще две оптимизационные фичи: Compact Object Headers и Linking Run-Time Images without JMODs.
Первая уменьшает размер любого объекта в памяти, оптимизируя заголовки. Вторая - уменьшает объем JDK, убирая оттуда JMOD файлы. JMOD появились вместе с модулями Java как развитие jar.
И классы в jmod файлах уже есть в JDK, т.е. имеем дублирование. Сейчас его убрали, размер JDK стал меньше на 25%. Важно в облаках с тысячами микросервисов.
На самом деле технология модулей в Java до сих пор не прижилась в коммерческой разработке, но команда Java не сдается)
Module Import Declarations - можно разом импортировать все классы в модуле. С одной стороны загрязняется область видимости, с другой - удобно.
Markdown Documentation Comments: Markdown - стандарт документации в ИТ в целом, получаем больше возможностей в JavaDoc. Да, JavaDoc нужны не всегда, но пригодится.
Фичи с JFR в названии - допилен профайлер: меньше влияние на исполнение кода (JFR Cooperative Sampling), больше данных (JFR Method Timing & Tracing).
Unnamed Variables & Patterns: _ (подчеркивание) обозначает для компилятора и валидаторов неиспользуемую переменную. Java пополнила длинный список языков, где это уже есть)
Scoped Values - более безопасный вариант Thread Local.
Также дошли до prod ready версии фичи из моего поста про Java 22 https://t.me/javaKotlinDevOps/278
* Launch Multi-File Source-Code Programs
* Implicitly Declared Classes and Instance Main Methods
* Stream Gatherers
* Class-File API
* Statements before super
Итого - решаются проблемы с производительностью и объемом, допиливается функционал (стримы, модули, JFR, Thread Local, GC), стандартизируются API (Class-File API), немного синтаксического сахара (_).
А String templates https://t.me/javaKotlinDevOps/246 выкинули. Слишком отличается от мэйнстрима, я про идею процессора STR."xxx", обрабатывающего строки
#java #jdk #java_new_version
Я о Java 25.
Вышла не вчера, поэтому также вышла и хорошая статья с обзором нововведений https://habr.com/ru/companies/T1Holding/articles/946778/.
Там даже табличка включения новых фич от 21 до 25 версии есть. И примеры кода - было\стало.
И от меня как всегда пару комментариев)
Для начала бросаются в глаза две фичи со "странным" названием Quantum-Resistant ...
Почему бросаются - квантовые компьютеры ожидаются в промышленном использовании в течение 10+ лет, а устойчивые к взлому квантовым компьютером алгоритмы в Java появились уже сейчас.
С - стратегия.
Б - банковское ПО)
Три фичи со словами Ahead-of-Time, главная из них - Ahead-of-Time Class Loading & Linking.
Это дальнейшее развитие темы CDS https://t.me/javaKotlinDevOps/316
Т.е. ускорение старта приложения.
Если CDS убирает этап верификации классов сохраняя в архиве уже проверенные классы,
то Ahead-of-Time Class Loading & Linking как следует из названия сохраняет всю необходимую для работы с классами информацию. Так сказать в распакованном виде, поэтому ее сразу можно грузить в Metaspace.
Одно но: набор классов у всех разный, поэтому нужно запустить приложение в тестовом режиме и собрать данные по актуальным классам, которые и будут сохранены в архиве.
Заодно сохраняется и статистика их использования (Ahead-of-Time Method Profiling), что позволяет при старте JVM сразу запустить компиляцию часто используемых методов.
Последняя фича - это offline Profile-Guided Optimization https://t.me/javaKotlinDevOps/315, которая ранее была killer feature коммерческих JVM: Azul ReadyNow и GraalVM Enterprise Native Image.
Итоговое ускорение загрузки: 42% vs 33% у CDS https://www.happycoders.eu/java/ahead-of-time-class-loading-and-linking/
Есть еще две оптимизационные фичи: Compact Object Headers и Linking Run-Time Images without JMODs.
Первая уменьшает размер любого объекта в памяти, оптимизируя заголовки. Вторая - уменьшает объем JDK, убирая оттуда JMOD файлы. JMOD появились вместе с модулями Java как развитие jar.
И классы в jmod файлах уже есть в JDK, т.е. имеем дублирование. Сейчас его убрали, размер JDK стал меньше на 25%. Важно в облаках с тысячами микросервисов.
На самом деле технология модулей в Java до сих пор не прижилась в коммерческой разработке, но команда Java не сдается)
Module Import Declarations - можно разом импортировать все классы в модуле. С одной стороны загрязняется область видимости, с другой - удобно.
Markdown Documentation Comments: Markdown - стандарт документации в ИТ в целом, получаем больше возможностей в JavaDoc. Да, JavaDoc нужны не всегда, но пригодится.
Фичи с JFR в названии - допилен профайлер: меньше влияние на исполнение кода (JFR Cooperative Sampling), больше данных (JFR Method Timing & Tracing).
Unnamed Variables & Patterns: _ (подчеркивание) обозначает для компилятора и валидаторов неиспользуемую переменную. Java пополнила длинный список языков, где это уже есть)
Scoped Values - более безопасный вариант Thread Local.
Также дошли до prod ready версии фичи из моего поста про Java 22 https://t.me/javaKotlinDevOps/278
* Launch Multi-File Source-Code Programs
* Implicitly Declared Classes and Instance Main Methods
* Stream Gatherers
* Class-File API
* Statements before super
Итого - решаются проблемы с производительностью и объемом, допиливается функционал (стримы, модули, JFR, Thread Local, GC), стандартизируются API (Class-File API), немного синтаксического сахара (_).
А String templates https://t.me/javaKotlinDevOps/246 выкинули. Слишком отличается от мэйнстрима, я про идею процессора STR."xxx", обрабатывающего строки
#java #jdk #java_new_version
Хабр
Возвращение LTS: ты не пройдёшь… мимо новых фич Java 25
В одной из моих предыдущих статей я писал о фичах между LTS-версиями Java 17 и 21 . Сегодня, два года спустя ( Как?! Уже два года?! ), выходит новый LTS-релиз — Java 25 . Подавляющее большинство...
Серия "хозяйке на заметку", а точнее разработчику библиотек на заметку.
Разработка библиотек отличается от разработки приложения тем, что публичные API в них живут намного дольше, и об этом надо помнить.
Любое публичное API, т.е. все public классы и методы, должно быть обратно совместимым как минимум в текущей мажорной версии.
Но жизнь как всегда сложнее. И что же у нас есть?
Java
1) объявить метод устаревшим с какой-то версии - @Deprecated.
Причем эту аннотацию можно не просто повесить на метод, у нее есть два поля: forRemoval и since, см. https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Deprecated.html
2) указать на что заменяем метод. @Deprecated не предоставляет такого механизма.
Но есть на свете добрые люди: https://errorprone.info/docs/inlineme
Как это может быть использовано:
а) статический анализ, собственно errorprone плагин: https://errorprone.info/docs/installation
б) миграция: https://docs.openrewrite.org/recipes/java/logging/log4j/inlinemethods
3) скрыть метод для потребителей не удаляя его из кодовой базы библиотеки. Т.е. оставляя его для тулов или для внутреннего использования. Java - снова нет( И даже добрые не помогли(
4) указать степень зрелости API. Стандартно - опять нет, но есть такая библиотечка @API Guardian https://github.com/apiguardian-team/apiguardian, позволяющая пометить API примерно так:
Используется в JUnit, к слову.
Более простая альтернатива: @Beta из Guava, https://guava.dev/releases/23.4-jre/api/docs/com/google/common/annotations/Beta.html
5) потребовать у клиента явного подтверждения в коде, что он готов использовать бета-версию, а не просто warning компилятора - увы, нет.
Kotlin
1) @Deprecated
2) @Deprecated(replaceWith) https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-replace-with/
3) @Deprecated(level) https://www.baeldung.com/kotlin/deprecation
4-5) Механизм Opt-In: https://kotlinlang.org/docs/opt-in-requirements.html#opt-in-to-inherit-from-a-class-or-interface
Все это, естественно, поддерживается в IDEA из коробки.
Плюс в Kotlin можно использовать @API Guardian
Получилась реклама Kotlin, что не удивительно, учитывая время его появления и назначение языка.
#api #java #kotlin
Разработка библиотек отличается от разработки приложения тем, что публичные API в них живут намного дольше, и об этом надо помнить.
Любое публичное API, т.е. все public классы и методы, должно быть обратно совместимым как минимум в текущей мажорной версии.
Но жизнь как всегда сложнее. И что же у нас есть?
Java
1) объявить метод устаревшим с какой-то версии - @Deprecated.
Причем эту аннотацию можно не просто повесить на метод, у нее есть два поля: forRemoval и since, см. https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Deprecated.html
2) указать на что заменяем метод. @Deprecated не предоставляет такого механизма.
Но есть на свете добрые люди: https://errorprone.info/docs/inlineme
Как это может быть использовано:
а) статический анализ, собственно errorprone плагин: https://errorprone.info/docs/installation
б) миграция: https://docs.openrewrite.org/recipes/java/logging/log4j/inlinemethods
3) скрыть метод для потребителей не удаляя его из кодовой базы библиотеки. Т.е. оставляя его для тулов или для внутреннего использования. Java - снова нет( И даже добрые не помогли(
4) указать степень зрелости API. Стандартно - опять нет, но есть такая библиотечка @API Guardian https://github.com/apiguardian-team/apiguardian, позволяющая пометить API примерно так:
@API(status = STABLE, since = "1.0")
public class StableService {
@API(status = EXPERIMENTAL)
public void experimentalMethod() {
}
@API(status = DEPRECATED, since = "2.0")
public void deprecatedMethod() {
}
@API(status = INTERNAL)
public void internalMethod() {
}
}
Используется в JUnit, к слову.
Более простая альтернатива: @Beta из Guava, https://guava.dev/releases/23.4-jre/api/docs/com/google/common/annotations/Beta.html
5) потребовать у клиента явного подтверждения в коде, что он готов использовать бета-версию, а не просто warning компилятора - увы, нет.
Kotlin
1) @Deprecated
2) @Deprecated(replaceWith) https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-replace-with/
3) @Deprecated(level) https://www.baeldung.com/kotlin/deprecation
4-5) Механизм Opt-In: https://kotlinlang.org/docs/opt-in-requirements.html#opt-in-to-inherit-from-a-class-or-interface
// Library code
@RequiresOptIn(message = "This API is experimental. It could change in the future without notice.")
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
annotation class MyDateTime
@MyDateTime
// A class requiring opt-in
class DateProvider
// Client code
@OptIn(MyDateTime::class)
// Uses DateProvider
fun getDate(): Date {
val dateProvider: DateProvider
// ...
}
Все это, естественно, поддерживается в IDEA из коробки.
Плюс в Kotlin можно использовать @API Guardian
Получилась реклама Kotlin, что не удивительно, учитывая время его появления и назначение языка.
#api #java #kotlin
Oracle
Deprecated (Java SE 17 & JDK 17)
declaration: module: java.base, package: java.lang, annotation type: Deprecated
null safety в Java - счастье на горизонте?)
Я уже писал про проблему null safety в Java, особенно ярко видимую на фоне Kotlin.
https://t.me/javaKotlinDevOps/98
В посте по ссылке выше разработчики Kotlin собрали поддерживаемые ими виды аннотаций а-ля @NotNull https://kotlinlang.org/docs/java-interop.html#nullability-annotations
И их число говорит о многом, а точнее о состоянии разброда и шатания в Java мире.
Так вот - похоже в войне Nullable аннотаций наметился победитель, и это JSpecify https://jspecify.dev/docs/user-guide/.
С одной стороны это очередная внешняя библиотека:
Которую поддерживает IDEA при поиске проблем. Но она и другие библиотеки поддерживает.
Что же изменилось?
А то, что собрался ряд достаточно известных компаний: Google, Oracle, JetBrains, Uber, VMware/Broadcom (а значит и Spring), и они стандартизировали именно JSpecify.
Что это значит, ряд примеров:
1) Spring переводит свой фреймворк на JSpecify к Spring 7\Spring Boot 4
2) про JetBrains и IDEA c Kotlin я уже сказал
3) Google внедряет новые аннотации в Guava. И наверняка куда-то еще)
...
Две основные фишки нового подхода:
1) Uber доработала плагин компилятора NullAway на основе errorprone:
и warning в IDEA легким движением руки превращается в error компиляции.
Работает в JDK 17,21 и 22+ https://bugs.openjdk.org/browse/JDK-8225377
Аналогично можно сделать в Maven.
2) Другое важное изменение - возможность задавать значение null safety по умолчанию для пакета, модуля или класса.
Эти объявления означают, что все поля и переменные в классе или пакете должны быть not null.
А если null значение все же нужно - нужно явно пометить его аннотацией @Null
Чтобы заменить старые аннотации на новые есть правила OpenRewrite https://docs.openrewrite.org/recipes/java/jspecify/jspecifybestpractices
Пару ложек дегтя:
1) Oracle в JDK пока аннотации не внедряет. Зато JDK пропатчила начиная с 17-й, чтобы валидация на этапе компиляции заработала.
2) Hibernate присматривается https://github.com/hibernate/hibernate-orm/discussions/6220.
Что я могу сказать в итоге - удачи, дело нужное!
А в прикладе внедрять уже можно. Ситуация НЕ похожа на известную шутку: было 10 разных стандартов, люди решили это изменить и их стало одиннадцать)
Проблема есть, и массовому внедрению ее решения мешал по большому счету тот факт, что единого решения не было.
#null_safety #java
Я уже писал про проблему null safety в Java, особенно ярко видимую на фоне Kotlin.
https://t.me/javaKotlinDevOps/98
В посте по ссылке выше разработчики Kotlin собрали поддерживаемые ими виды аннотаций а-ля @NotNull https://kotlinlang.org/docs/java-interop.html#nullability-annotations
И их число говорит о многом, а точнее о состоянии разброда и шатания в Java мире.
Так вот - похоже в войне Nullable аннотаций наметился победитель, и это JSpecify https://jspecify.dev/docs/user-guide/.
С одной стороны это очередная внешняя библиотека:
dependencies {
implementation 'org.jspecify:jspecify:1.0.0'
....
}Которую поддерживает IDEA при поиске проблем. Но она и другие библиотеки поддерживает.
Что же изменилось?
А то, что собрался ряд достаточно известных компаний: Google, Oracle, JetBrains, Uber, VMware/Broadcom (а значит и Spring), и они стандартизировали именно JSpecify.
Что это значит, ряд примеров:
1) Spring переводит свой фреймворк на JSpecify к Spring 7\Spring Boot 4
2) про JetBrains и IDEA c Kotlin я уже сказал
3) Google внедряет новые аннотации в Guava. И наверняка куда-то еще)
...
Две основные фишки нового подхода:
1) Uber доработала плагин компилятора NullAway на основе errorprone:
tasks.withType(JavaCompile).configureEach {
options.errorprone {
disableAllChecks = true // Other error prone checks are disabled
option("NullAway:OnlyNullMarked", "true") // Enable nullness checks only in null-marked code
error("NullAway") // bump checks from warnings (default) to errors
option("NullAway:JSpecifyMode", "true") // https://github.com/uber/NullAway/wiki/JSpecify-Support
}
}и warning в IDEA легким движением руки превращается в error компиляции.
Работает в JDK 17,21 и 22+ https://bugs.openjdk.org/browse/JDK-8225377
Аналогично можно сделать в Maven.
2) Другое важное изменение - возможность задавать значение null safety по умолчанию для пакета, модуля или класса.
@NullMarked
package org.example;
@NullMarked
class MyClass {
Эти объявления означают, что все поля и переменные в классе или пакете должны быть not null.
А если null значение все же нужно - нужно явно пометить его аннотацией @Null
Чтобы заменить старые аннотации на новые есть правила OpenRewrite https://docs.openrewrite.org/recipes/java/jspecify/jspecifybestpractices
Пару ложек дегтя:
1) Oracle в JDK пока аннотации не внедряет. Зато JDK пропатчила начиная с 17-й, чтобы валидация на этапе компиляции заработала.
2) Hibernate присматривается https://github.com/hibernate/hibernate-orm/discussions/6220.
Что я могу сказать в итоге - удачи, дело нужное!
А в прикладе внедрять уже можно. Ситуация НЕ похожа на известную шутку: было 10 разных стандартов, люди решили это изменить и их стало одиннадцать)
Проблема есть, и массовому внедрению ее решения мешал по большому счету тот факт, что единого решения не было.
#null_safety #java
Telegram
(java || kotlin) && devOps
Всем привет!
Небольшое замечание. О важности проблемы null safety в Java говорит вот этот список различных видов @Null\@NotNull аннотаций Java, которые поддерживает Kotlin при проверке типов: https://kotlinlang.org/docs/java-interop.html#nullability-annotations…
Небольшое замечание. О важности проблемы null safety в Java говорит вот этот список различных видов @Null\@NotNull аннотаций Java, которые поддерживает Kotlin при проверке типов: https://kotlinlang.org/docs/java-interop.html#nullability-annotations…
🔥2
Концепция venv (virtualenv) в Python
Концепция крутая, как по мне ноутбуки и виртуальные окружения - две самые крутые фичи в Python.
Если вкратце о ее сути: ты создаешь для каждого проекта отдельную виртуальную среду, со своим интерпретатором Python (разные версии) и своим набором библиотек.
Это удобно, и решает проблему конфликта зависимостей. Небольшое уточнение: если бы все сервисы и библиотеки явно указывали версии зависимостей - конфликтов бы не было, но мы же говорим о реальном мире.
К слову, концепцию позаимствовала и Java, я про jenv - https://t.me/javaKotlinDevOps/442 - правда, ограничить можно только версию Java.
Но блин.
Почему утилит, реализующих виртуальные окружения столько:
- venv
- virtualenv
- uv
- Poetry
- PDM
- Hatch
- Rye
- Conda
- Mamba
- Micromamba
- Pixi
- Pipenv
- pyenv-virtualenv
- virtualenvwrapper
- Tox
- Nox
- Devbox
- Flox
- Devenv.sh
- Spack
- Vex
????
Явная иллюстрация анекдота про 10 стандартов)
Ясно, что они не идентичны по функционалу.
1) кто-то добавляет возможность менеджера пакетов (и это правильно),
2) кто-то позволяет формировать список зависимостей проекта requirements.txt (и это тоже правильно),
3) кто-то добавляет возможность делать lock зависимостей (спорная фича IMHO).
Кто-то просто устарел. Кто-то заточен для тестов, где нужна куча разных сред. Кто-то просто добавляет небольшие фишки в другой менеджер, типа убирает необходимость явно включать использование виртуального окружения в консоли (activate).
Но все же...
Причем 4 из них имеют официальный статус)
P.S. Самой крутой и современной считается uv. На данный момент.
#python #java #virtual_env
Концепция крутая, как по мне ноутбуки и виртуальные окружения - две самые крутые фичи в Python.
Если вкратце о ее сути: ты создаешь для каждого проекта отдельную виртуальную среду, со своим интерпретатором Python (разные версии) и своим набором библиотек.
Это удобно, и решает проблему конфликта зависимостей. Небольшое уточнение: если бы все сервисы и библиотеки явно указывали версии зависимостей - конфликтов бы не было, но мы же говорим о реальном мире.
К слову, концепцию позаимствовала и Java, я про jenv - https://t.me/javaKotlinDevOps/442 - правда, ограничить можно только версию Java.
Но блин.
Почему утилит, реализующих виртуальные окружения столько:
- venv
- virtualenv
- uv
- Poetry
- PDM
- Hatch
- Rye
- Conda
- Mamba
- Micromamba
- Pixi
- Pipenv
- pyenv-virtualenv
- virtualenvwrapper
- Tox
- Nox
- Devbox
- Flox
- Devenv.sh
- Spack
- Vex
????
Явная иллюстрация анекдота про 10 стандартов)
Ясно, что они не идентичны по функционалу.
1) кто-то добавляет возможность менеджера пакетов (и это правильно),
2) кто-то позволяет формировать список зависимостей проекта requirements.txt (и это тоже правильно),
3) кто-то добавляет возможность делать lock зависимостей (спорная фича IMHO).
Кто-то просто устарел. Кто-то заточен для тестов, где нужна куча разных сред. Кто-то просто добавляет небольшие фишки в другой менеджер, типа убирает необходимость явно включать использование виртуального окружения в консоли (activate).
Но все же...
Причем 4 из них имеют официальный статус)
P.S. Самой крутой и современной считается uv. На данный момент.
#python #java #virtual_env
Telegram
(java || kotlin) && devOps
Жонглирование JDK
Иногда нужно вести разработку нескольких сервисов, требующих разных версий JDK. Или нескольких релизов одного и того же сервиса. Или какое-то ПО на компьютере требует одной версии JDK, а разработка другой.
Все эти проблемы решает утилита…
Иногда нужно вести разработку нескольких сервисов, требующих разных версий JDK. Или нескольких релизов одного и того же сервиса. Или какое-то ПО на компьютере требует одной версии JDK, а разработка другой.
Все эти проблемы решает утилита…