6. Jigsaw: JEPs
● JEP 200: The Modular JDK
● JEP 260: Encapsulate Most Internal APIs
● JEP 261: Module System
● JEP 220: Modular Run-Time Images
● JEP 282: jlink: The Java Linker
7. JEP 200: The Modular JDK
http://cr.openjdk.java.net/~mr/jigsaw/jdk9-module-summary.html
8. JEP 260: Encapsulate Most Internal APIs
● Публичные
○ java.*
○ javax.*
○ com.sun.*
● Внутренние
○ sun.*
9. JEP 260: Encapsulate Most Internal APIs
Внутренние API:
● Некритичные
(sun.misc.BASE64Decoder → j.u.Base64)
● Критичные (sun.misc.Unsafe)
10. JEP 260: Encapsulate Most Internal APIs
● Неиспользуемые: инкапсулированы
● С заменой: инкапсулированы
● Остальные:
○ Помечены @Deprecated
○ Будут инкапсулированы или удалены
○ Доступны для использования через
Похоже, остались самые стойкие. Для вас мы приберегли кишочки.
Вот такую рекламу Java 9 заказал Oracle у Lionsgate.
Начнём издалека. Что же такое проект Jigsaw, зачем он вообще нужен?
Упростить разработку и поддержку библиотек и крупных приложений
Повысить безопасность платформы Java SE в целом и JDK в частности
Улучшить производительность
Снизить потребление ресурсов для использования в IoT / cloud
Как же будут достигаться поставленные цели?
Дизайн и разработка модульной системы для платформы (Java SE), применение её к референсной имплементации (JDK 9).
Модульная система позволяет раздробить саму JDK, а также проста в использовании разработчиками.
Модули - это всего лишь способ группировки пакетов (классов), нативного кода, ресурсов и конфигураций. Модули не затрагивают проблему версионирования.
Модуль - это специальным образом собранный JAR-файл, содержащий классы в пакетах, ресурсы, конфигурацию и специальный дескриптор module-info.java. В дескрипторе указываются:
Модули, от которых зависит данный модуль
Экспортируемые пакеты
Провайдеры сервисов, ака SPI.
Jigsaw состоит из нескольких enhancement proposals. Для разработчиков, ИМХО, наиболее важными станут 260, 261, 282.
Отныне, вся JDK разбита на небольшие, логически сгруппированные модули. Но не беспокойтесь, IDEA уже понимает это.
JEP 201 нам не интересен: он больше предназначен для разработчиков JDK и описывает изменения в структуре её исходного кода.
О том, как использовать модули в своих приложениях мы поговорить чуть позже, а сейчас давайте ознакомимся с предлагаемой классификацией существующих Java API.
… внимательнее посмотрим на внутренние API… Они бывают:
Некритичные: неиспользуемые за пределами JDK или те, для которых существует замена
Критичные: сложно или практически невозможно реализовать вне JDK
Как видим, ничего по-настоящему страшного пока не произошло.
Даже для sun.misc.Unsafe нашлась замена (ну почти, об этом дальше).
Нет, не работаем.
Если вы полагаете, что раз в вашем коде не встречается “importsun.misc.Unsafe;”,то вам не о чем волноваться, вы ошибаетесь. Вот результат анализа последней версии довольно популярной библиотеки LMAX Disruptor утилитой jdeps. Проверьте ваши проекты заранее!
Oracle заботится о разработчиках!
При попытке загрузки классов из пакетов, не входящих ни в один модуль, поиск продолжиться в classpath и, в случае успеха, найденные классы / пакеты попадут в unnamed module, экспортирующий все свои пакеты и читающий все остальные модули!
Любой JAR, помещённый в modulepath, даже если это не Java 9 модуль, автоматически превращается в модуль, экспортирующий все свои пакеты и читающий все остальные модули!
Таблица показывает, что бывает с разными типами файлов при помещении в те или иные пути…
План действий на ближайшие пару лет.
Некоторым из методов Unsafe нашлась замена.
Отлично, работаем дальше!
В общем: инфраструктура для работы с модулями. Самое интересное тут - новый формат файлов: JMOD. Это блоб, ZIP, позволяющий хранить, среди прочего, нативный код и другие вещи, не совсем подходящие для JAR-файлов. Все модули JDK упакованы в JMOD, но он не обязателен к использованию.
Изменилась и структура директорий JDK. Нет больше папки jre, нет rt.jar и tools.jar.
jlink, по сути, собирает вашу собственную (уникальную и неповторимую) JVM лишь с необходимыми вам модулями, а также, опционально, создаёт нативный исполняемый файл для вызова ваших Main-классов!
И это меняет правила игры!
Демо Jigsaw modules + jlink
Кто знает, что такое OSGi? Провели параллели, да?
Мне навсегда запомнилась фраза моего тимлида, когда я впервые увидел OSGi (не думаю, что он автор): если ты не знаешь, что такое OSGi, то он тебе не нужен.
Модули похожи на OSGi не только концептуально, но и повторяют, ИМХО, его историю:
Не-упрощение разработки для простых смертных. Т.е. как минимум, легче разрабатывать станет. Может - сложнее.
Первоначальное отсутствие хорошего инструментария
“Частичный” переход библиотек. Для тех, кто не в курсе: большАя часть библиотек в Maven Central до сих пор не имеют OSGi-манифестов, что вызывает некоторые неудобства при желании их использовать в OSGi-окружениях.
В целом, модули имеют больше значения для разработчиков JDK, крупных библиотек и приложений (аппликейшн серверов). Но и обычный разработчик может столкнутся с ситуациями, где они просто необходимы: jlink.
JAR с версиями классов для разных JVM.
Здесь бы хотел немного отойти от темы доклада и погоревать об Oracle, его заботе о разработчиках и инструментах. А именно: как собирать мульти-релизные JAR-файлы кроме как не через утилиты из JDK? Где поддержка со стороны Gradle / Maven. Сюда же работа с jlink, модулями вообще. Поддержки пока нет!
JEP 250: Store Interned Strings in CDS Archives
CDS (Class Data Sharing) архив — это специальный файл, создаваемый JDK, содержащий какой-то набор классов, используемых JVM во внутреннем представлении. Внутреннее представление - это не .class файлы, а просто дамп областей памяти работающей JVM с теми классами. CDS архив переиспользуется несколькими JVM, запущенными одновременно, через memory mapping. Как несложно понять из этого упрощенного описания CDS архив немного улучшает время запуска новых JVM (оно не тратится на преобразование .class формата во внутренние структуры). Также в этом файле хранятся и некоторые строковые константы, но, почему-то в UTF-8. Во время использования этих строк, они преобразуются в String, на что тратится время и дополнительная память. К тому же, такие строки не интернированы, т.е. Существуют в нескольких инстансах. Предлагается использовать char[] напрямую.
JEP 254: Compact Strings
До Java 9 содержимое строк хранилось в char[], подразумевая кодировку UTF-16 (два байта на любой символ). Анализ исходного кода многих приложений, проведённый разработчиками JDK, показал, что большинство строк на самом деле используют символы из Latin-1 набора, для представления которых достаточно одного байта. Предлагается изменить внутреннее представлние класса String: хранить содержимое либо в byte[] (если все символы укладываются в Latin-1) либо в char[] (в противном случае) + флаг.
JEP 280: Indify String Concatenation
Многие знают, что конкатенация строк в коде преобразуется в вызовы StringBuilder::append в байткоде. Это, в принципе, неплохой подход, но он не позволяет делать некоторые оптимизации (например пре-выделение места в StringBuilder без изменения байткода / использования дополнительных флагов). Предлагается изменить байткод конкатенации строк на динамический вызов (invokedynamic) java.lang.invoke.StringConcatFactory. Это позволит иметь всегда одинаковый байткод конкатенации, а оптимизации будут проводится непосредственно в StringConcatFactory. invokedynamic, если помните “запоминает” аргументы вызова метода и связывает их с той или иной имплементацией байт-кода при первом вызове. Так разработчикам JDK будет проще выкатывать новые оптимизации, которые будут доступны без перекомпиляции кода, просто при запуске на новых версиях JVM.
Как видите, эти изменения не имеют прямого влияния на простых разработчиков, типа нас с вами, но строки в Java 9 стали ещё лучше!
Обращаю ваше внимание, что UTF-8 доступна для использования в *.properties-файлах лишь при загрузке их через класс java.util.ResourceBundle, а не java.util.Properties. При загрузке UTF-8 файлов через класс Properties вы получите кракозябры, так как он по-прежнему использует Latin-1.
~8000 символов в 10-ти блоках для 6-ти систем письма и не только!
А это означает поддержку:
Скин-тонов для некоторых эмодзи
Символ лари (грузинская валюта)
5771 символ CJK (усилие по выделению общего подмножества из иероглифов китайских, японских и корейских систем письма)
Строчного письма чероки
Письменностей ахом, древнеанатолийского языка, венгерских рун, мёртвых диалектов арамейских языков, одного из современных диалектов пенджабского и жестового письма
И нет, я не выдумал эти языки. Они реально существуют или существовали.
Давайте взбодримся и ответим на парочку несложных вопросов.
Похоже, что 60, ведь это целых 9 релизов после 51?!
Неверно! В 60-м релизе есть лишь несколько минорных изменений, а в целом они одинаковы.
Правильный ответ, кстати: Java 9!
Ни одного! 8u60 выпустили сразу после 8u51. Релизов 52, 53 и 57 не существует.
Почему?
Версии Java делящиеся нацело на 20 не содержат секьюрити фиксов! А версии, содержащие секьюрити фиксы должны быть нечётными, с шагом в 5 или 6 (чтобы обеспечивать нечётность)! Таким образом, после 51-го релиза с секьюрити фиксами следующим мог бы стать 57-й или 60-й, время выдалось спокойное и дыр не находили: выпустили 8u60.
Следующим мог бы стать 8u65 (очевидно безопаснее 8u60 и 8u51) или 8u80 (равный по безопасности).
Или нет?
Всё это безумие заменили на что-то, похожее на Semver.
По-прежнему сохранились билды, патчи, релиз-кандидаты и early access, но в целом - так.
И, да, если вы где-то полагались на единичку в версиях - будьте осторожны, её убрали. Совсем.
А так могли бы выглядеть версии Java 8. MINOR и SECURITY тут не совсем случайны, но могу быть неверными: я посчитал сколько каких релизов было в Java 8 и прикинул на пальцах.
Немного нагляднее, верно?
Уменьшение пауз в угоду пропускной способности.
Что это значит для нас, простых смертных? Ну, во-первых, ребята из JDK решили что так нам будет лучше. Во-вторых, если вы всё ещё спрашиваете / отвечаете про GC / memory layout на собесах - обновите собственные знания.