Как собрать java приложение
Обычно удобно объединять множество файлов классов Java в один архивный файл.
В этом уроке мы рассмотрим все тонкости работы с jar – или J ava AR chive – файлами на Java.
В частности, мы возьмем простое приложение и рассмотрим различные способы его упаковки и запуска в виде jar. Мы также ответим на некоторые любопытные вопросы, такие как как легко прочитать файл манифеста jar по пути.
2. Настройка программы Java
Прежде чем мы сможем создать запускаемый jar-файл, наше приложение должно иметь класс с основным методом . Этот класс обеспечивает нашу точку входа в приложение:
3. Команда Jar
Теперь, когда мы все настроили, давайте скомпилируем наш код и создадим наш jar-файл.
Мы можем сделать это с помощью javac из командной строки:
Команда javac создает JarExample.class в каталоге com/baeldung/jar . Теперь мы можем упаковать это в файл jar.
3.1. Использование параметров по умолчанию
Чтобы создать файл jar, мы будем использовать кувшин команда.
Чтобы использовать команду jar для создания файла jar, нам нужно использовать опцию c , чтобы указать, что мы создаем файл, и опцию f , чтобы указать файл:
3.2. Установка основного класса
Полезно, чтобы манифест файла jar включал основной класс.
Манифест-это специальный файл в банке, расположенный в каталоге META-INF и названный MANIFEST.MF . Файл манифеста содержит специальную метаинформацию о файлах в файле jar.
Некоторые примеры того, для чего мы можем использовать файл манифеста, включают установку точки входа, установку информации о версии и настройку пути к классу.
Используя опцию e , мы можем указать нашу точку входа, и команда jar добавит ее в сгенерированный файл манифеста.
Давайте запустим jar с указанной точкой входа:
3.3. Обновление содержания
Допустим, мы внесли изменения в один из наших классов и перекомпилировали его. Теперь нам нужно обновить наш jar-файл.
Давайте используем команду jar с параметром u для обновления ее содержимого:
3.4. Настройка файла манифеста
В некоторых случаях нам может потребоваться больше контроля над тем, что входит в наш файл манифеста. Команда jar предоставляет функциональные возможности для предоставления нашей собственной информации о манифесте.
Давайте добавим частичный файл манифеста с именем example_manifest.txt чтобы ваше приложение установило нашу точку входа:
Информация о манифесте, которую мы предоставляем, будет добавлена к тому, что генерирует команда jar, так что это единственная строка, которая нам нужна в файле.
Важно, чтобы мы заканчивали наш файл манифеста символом |/newline . Без новой строки наш файл манифеста будет молча проигнорирован.
С этой настройкой давайте снова создадим нашу банку, используя нашу информацию о манифесте и опцию m :
3.5. Подробный Вывод
Если нам нужна дополнительная информация из команды jar , мы можем просто добавить опцию v для verbose.
Давайте запустим нашу команду jar с параметром v :
4. Использование Maven
4.1. Конфигурация по Умолчанию
Мы также можем использовать Maven для создания нашей банки. Поскольку Maven предпочитает условность конфигурации, мы можем просто запустить пакет для создания нашего jar-файла.
По умолчанию наш jar-файл будет добавлен в папку target в нашем проекте.
4.2. Указание основного класса
Мы также можем настроить Maven для указания основного класса и создания исполняемого jar-файла .
5. Использование Пружинного Ботинка
5.1. Использование Maven и Defaults
Если мы используем Spring Boot с Maven, мы должны сначала подтвердить, что наш параметр упаковки установлен в jar , а не war в нашем pom.xml файл.
Как только мы узнаем, что это настроено, мы можем запустить пакет цель:
5.2. Установка точки входа
Установка нашего основного класса-это то, где мы находим различия между созданием jar с обычным Java-приложением и fat jar для приложения Spring Boot . В приложении Spring Boot основной класс на самом деле является org.springframework.boot.loader.Ярлаунчер .
Хотя наш пример не является приложением Spring Boot, мы могли бы легко настроить его как консольное приложение Spring Boot .
Наш основной класс должен быть указан как начальный класс:
Мы также можем использовать Gradle для создания Spring Boot fat jar .
6. Запуск банки
6.1. Вывод основного класса
Поскольку мы пошли дальше и убедились, что наш основной класс указан в манифесте, мы можем использовать опцию -jar команды java для запуска нашего приложения без указания основного класса:
6.2. Указание основного класса
Мы также можем указать основной класс, когда мы запускаем наше приложение. Мы можем использовать опцию -cp , чтобы убедиться, что наш jar-файл находится в пути к классу, а затем предоставить ваш основной класс в формате package.className :
Использование разделителей путей вместо формата пакета также работает:
6.3. Перечисление содержимого банки
Мы можем использовать команду jar для перечисления содержимого нашего файла jar:
6.4. Просмотр файла манифеста
Поскольку может быть важно знать, что находится в нашем файле MANIFEST.MF , давайте рассмотрим быстрый и простой способ заглянуть в содержимое, не выходя из командной строки.
Давайте воспользуемся командой unzip с параметром-p:
7. Заключение
В этом уроке мы настроим простое Java-приложение с классом main .
Затем мы рассмотрели три способа создания jar-файлов: с помощью команды jar , с помощью Maven и с помощью приложения Maven Spring Boot.
После того, как мы создали наши jar-файлы, мы вернулись в командную строку и запустили их с выведенным и заданным основным классом.
Мы также узнали, как отображать содержимое файла и как отображать содержимое одного файла в банке.
Статья написана для тех, кто умеет писать простейшие программы на java, но не умеет их собирать. Этим людям уже известно, что такое классы, что такое пакеты и зачем нужен public static main(String[] argv), но код без среды разработки они не запускали, да и не понимают кому и зачем это вообще может понадобиться.
Сразу скажу, что Java программиста, который не может собрать свою программу из консольки, на работу не возьмут, и это в общем более чем достаточная причина, чтобы научиться искусству обращения с системами сборки. Остальное детали, которым и посвящена статья.
Я принципиально не буду обсуждать в статье ничего, кроме сборки минимального HelloWorld. Также я постараюсь опустить все технические детали, которые можно опустить и подробно раскрыть всё, без понимания чего обойтись нельзя.
Для того, чтобы воспользоваться информацией из статьи нужно знать, что такое xml, переменные окружения, зачем нужна переменная окружения PATH и как пользоваться консолью.
Зачем собирать код без IDE
Первый вопрос, который возникает у начинающего разработчика — как в реальной жизни может пригодиться умение собирать код без среды разработки. Она ведь установлена и настроена у всех — это первое, что делает программист, когда приходит на проект.
Ответ простой — для того, чтобы нормально организовать рабочий процесс — код нужно регулярно собирать, проверять что он вообще компилируется, а потом, для того чтобы убедиться в работоспособности кода, прогонять тесты.
Можно, конечно, выделить специального человека, который будет раз в 15 минут запускать IDE и проводить описанные выше процедуры, но это безумие, такие вещи следует делать автоматически.
Уметь собирать код без среды разработки — суровая необходимость. Настолько суровая, что для решения этой задачи существует особый класс программного обеспечения, называемого системами сборки.
Что такое система сборки?
Система сборки это программа, которая собирает другие программы. На вход система сборки получает исходный код, а на выход выдаёт программу, которую уже можно запустить.
Чем она отличается от компилятора? Если коротко, то система сборки вызывает компилятор при своей работе, а компилятор о существовании системы сборки даже не подозревает.
Если более длинно, то сборка, помимо компиляции, включает в себя ещё целый спектр задач, для решения которых компилятор не пригоден от слова совсем.
Например, если программе для работы нужны какие-нибудь картинки, то положить их в директорию с программой — задача системы сборки. Если программе нужны сторонние библиотеки, то положить их в директорию с программой — задача системы сборки. Ну и так далее.
И да, если автоматическая сборка проекта настроена и работает, то нет нужды вручную конфигурировать IDE — современная среда разработки сгенерирует проект самостоятельно, достаточно показать ей где находится конфигурация для системы сборки.
Систем сборки для java по большому счёту 3 — ant, maven и gradle. ant отживает свой век, нынче его используют либо ретрограды, либо реально крутые чуваки, типа Антона Кекса, gradle пока удел хипстеров, а вот maven — стандарт индустрии. Уметь им пользоваться просто необходимо.
Как установить maven
Maven устанавливается просто копированием в нужную директорию — никакого инсталлера нет. Как и в случае с большинством консольных утилит для использования достаточно добавить директорию maven/bin в переменную окружения PATH.
То есть, если maven находится в d:/soft/maven, то в PATH надо добавить d:/soft/maven/bin
Ещё для работы maven потребует переменную JAVA_HOME, которая указывает на JDK. Если JDK находится в C:/Program Files/Java/jdk1.8.0_05, то именно такое значение нужно поместить в JAVA_HOME. Добавлять bin в конец не нужно.
После этого можно попробовать написать в консоли
Если получится, значит maven установлен.
Как структурировать проект для maven
В терминологии maven совокупность файлов с исходным кодом программы, файлов настроек и всего такого называется проектом. Директория, в которой располагаются эти файлы, называется корневой директорией проекта. В дальшейшем я буду обозначать эту директорию как <project>
Как известно, язык программирования java навязывает программисту структуру директорий, которая диктует расположение файлов с классами. Напимер класс с полным именем com.app.HelloWorld должен находиться в файле com/app/HelloWorld.java и никак иначе.
Maven добавляет к этому ограничению ещё одно — исходный код должен находиться в директории <project>/src/main/java. То есть класс com.app.HelloWorld maven будет искать в <project>/src/main/java/com/app/HelloWorld.java
Вот как будет выглядеть этот самый HelloWorld
Как сделать описание проекта
Но просто положить файлы в ожидаемую maven структуру директорий недостаточно. Для сборки проекта необходимо его описание в виде xml документа. Maven будет искать описание в корневой директории проекта в файле pom.xml .
Содержимое минимального файла pom.xml будет примерно следующим. Для прохождения туториала можно таким его и оставить, если ничего не поменять, код нормально соберётся.
Что тут было существенно важного и что надо запомнить? Запомнить надо вот эти три строки.
Эти три строки являются идентификатором программы для внешнего мира. Программа, она же результат работы по сборке проекта, в терминологии maven называется артефактом.
Непонятное слово артефакт используется здесь вместо понятного слова программа потому, что результатом работы системы сборки может быть не только собственно программа, но и библиотека или ещё что-нибудь эдакое. Комбинация параметров groupId, artifactId и version уникальна для каждого артефакта. Об уникальности этой комбинации должен позаботиться программист.
Технически, значения этих параметров могут быть любыми, но при их выборе строго рекомендуется соблюдать правила хорошего тона.
groupId
В groupId обычно находится название какого-нибудь пакета. Напомню, что название пакета согласно тем же правилам хорошего тона, должно быть именем веб-домена, владельцем которого является автор пакета, что позволяет худо-бедно обеспечить уникальность названия.
artifactId
В artifactId — строка с именем артефакта, которое придумывает его создатель. Как правило это какое-нибудь слово, иногда с разделителями в виде тире. Например hibernate-annotation-wat. artifactId должны быть уникальны в рамках groupId.
version
Ну и наконец version это версия артефакта, которую надо увеличивать при каждом более-менее значительном изменении. Версия обычно включает цифрры и буквы. Типа 1.0-SNAPSHOT
Как собрать проект
Теперь, когда структура файлов проекта соответствует ожидаемой, а его описание присутствует в файле pom.xml, для того, чтобы собрать проект, осталось только открыть консоль, сменить текущую директорию на директорию проекта и написать в консоли:
После того, как maven закончит свою работу, в директории проекта появится директория target, в которой будет находиться скомпилированный код.
Скомпилированный java код выглядит так же, как исходный, только вместо файлов с расширением java в директориях, соответствующих названиями пакетов, находятся файлы с расширением class, в которых будет уже не исходный код, а код, предназначенный для интерпретации джава-машиной.
То есть теперь этот код можно запустить.
Как запустить проект
Чтобы запустить скомпилированный код, нужно в консоли из этой же директории набрать
После того, как maven перестанет качать всякую дрянь из интернета, где-то перед здоровой табличкой с надписью BUILD SUCCESS, появится строчка Hello World.
Код отработал, всё прошло удачно.
Вот так собирают java программы с помощью системы сборки maven.
Итого
maven ищет код для сборки в директории <project>src/main/java.
Инструкции по сборке maven будет искать в <project>/pom.xml
Результат работы системы сборки называется артефактом.
От программиста требуется задать groupId, artifactId и version
Сборка осуществляется командой mvn compile
Скомпилированный java код выглядит так же, как исходный код, но вместо файлов с расширением java, там будут файлы с расширением class.
Как скомпилировать программу?
- Есть исходный код в файле с именем НазваниеКласса.java;
- Если в коде нет ошибок, он компилируется в байт-код (в файл НазваниеКласса.class);
- Программа запускается.
Для чего нужна команда javac
Компиляция и выполнение нескольких классов
Для работы с несколькими классами нужен classpath. Он похож на файловую систему, в которой содержатся классы, а функцию папок выполняют пакеты (packages). На этом этапе стоит задуматься об отделении файлов исходного кода от скомпилированных файлов. Как правило исходники находятся в каталоге src, а скомпилированные классы — в bin. Например, у нас есть класс Box и класс BoxMachine , в котором содержится метод main . Класс Box : Он находится в пакете src, это необходимо зафиксировать. Класс BoxMachine : Этот класс также находится в пакете src. В методе main он создает пять объектов класса Box разного размера и выводит в консоль информацию о них. Чтобы скомпилировать эту группу классов, необходимо из главного каталога (в котором лежат папки src и bin) использовать команду javac с аргументами: -d — флаг, после которого следует указать расположение, куда попадут скомпилированные классы. Это очень удобно, так как перекладывать, например, 1000 классов — очень трудоемкий процесс. bin — название папки. ./src/* — расположение исходных файлов. * указывает, что необходимо скомпилировать все файлы. Теперь скомпилированные классы появились в папке bin. Для их запуска используется команда java из той же директории, также с аргументами: -classpath — флаг, после которого следует указать местоположение скомпилированных классов. Java будет искать главный класс и все сопутствующие именно в этой директории. ./bin — название папки, в которой находятся скомпилированные классы. BoxMachine — название главного класса. Как и в первом случае, не следует указывать .class , так как это название класса, а не файла. Вывод:
Создание JAR-файлов
Чтобы программу было легко переносить и запускать, можно собрать скомпилированные классы в jar-файл — архив классов. Главное отличие от zip или rar-архивов — наличие файла манифеста. В этом манифесте указывается главный класс, который будет запускаться при выполнении jar-файла, classpath, а также много дополнительной информации. В главном каталоге создадим файл manifest.mf. Его содержимое будет следующим: main-class указывает класс, который содержит метод main и будет выполнен при запуске. class-path — путь к скомпилированным классам или дополнительным библиотекам. Настало время собрать настоящую программу без IDE с помощью команды jar: -cmf — флаг, после которого следует указать путь к файлу манифеста. manifest.mf — путь к манифесту. box-machine.jar — название выходного jar-файла. -С — флаг, после которого указывается путь к скомпилированным классам. . — путь, куда будет помещен jar-файл. В нашем случае —это главный каталог. Теперь можно запустить. Запуск jar-файлов выполняется также с помощью команды java, но следом нужно указать флаг -jar : он говорит о том, что запускается Jar-файл, а второй аргумент — путь к jar -файлу, включая расширение: Вывод:
Компиляция в Java без IDE: обзор систем сборок
Несмотря на относительную простоту использования командной строки, с ее помощью очень сложно собирать средние и большие проекты. Это занимает много времени и чревато ошибками разной степени. К счастью, есть системы сборки, которые в разы облегчают процесс работы. Несколькими командами эта система может собрать проект любой сложности, а обилие плагинов, созданных за время существования таких систем, может избавить практически от любой головной боли.
Как скомпилировать Java?
Самые известные системы сборки на Java — это Ant, Maven и Gradle. Среди нет плохой или хорошей: каждая из них создана для решения определенных задач. Рассмотрим каждую из них подробнее.
- mkdir — создание директорий
- delete — удаление файлов и директорий
- javac — компиляция Java–кода
- java — запуск скомпилированного кода
Maven
Gradle
Это самая молодая система сборки, которая основывается на Ant и Maven. Главное отличие — работа на базе ациклического графа для определения порядка выполнения задач. Это очень полезно при более сложных задачах, например, инкрементальных и многопроектных сборках. При сборке с помощью Gradle также рекомендуется придерживаться структуры папок проекта Maven. Кстати, файл для сборки в Gradle он называется build.gradle и выглядит гораздо меньше, чем у Maven. Пример для наших классов: В файле происходит подключение плагинов, определение директории файлов исходного кода (если не используется структура проектов Maven), директория результатов сборки, имя главного класса, а также задачи по умолчанию. За запуск сборки отвечает команда gradle в директории, где лежит файл build.gradle:
Заключение
Команды java и javac редко используются Java-программистами. Такие инструменты, как Maven и Gradle делают их почти не нужными. Однако Maven и Gradle до сих пор не предоставляют полную поддержку для Java 9, поэтому, если вы хотите начать использовать её уже сейчас или просто хотите узнать некоторые полезные тонкости до официального релиза, стоит научиться вызывать java , javac и jar для управления своим кодом.
Статья призвана показать примеры использования этих команд, а также то, как эти команды изменились по сравнению с прошлыми версиями Java. Дополнительно будут рассмотрены новые инструменты: jdeps и jlink . Предполагается, что вы хоть немного знакомы с предыдущими версиями команд java / javac / jar и с модульной системой Java 9.
Установка Java 9
Сперва необходимо установить Java 9. Вы можете скачать её с сайта Oracle, но рекомендуется использовать SdkMAN!, так как в будущем он позволит вам с легкостью переключаться между разными версиями Java.
Можно установить SdkMAN! с помощью этой команды:
Посмотрите, какая сборка является последней:
Затем установите Java 9:
Теперь, если у вас установлены другие версии Java, вы можете переключаться между ними с помощью команды:
Компиляция и запуск «по-старому»
Для начала напишем какой-нибудь код, чтобы проверить наши инструменты. Если не использовать модульный дескриптор, то все выглядит так же, как и раньше.
Возьмем этот простой Java-класс:
Теперь, так как мы не использовали никаких особенностей Java 9, мы можем скомпилировать всё как обычно:
Команда создаст файл класса out/app/Main.class . Запустить его можно так же, как и в прошлых версиях:
Программа выведет Hello Java 9 .
Sportmaster Lab , Красноярск, Санкт-Петербург, Москва , От 100 000 до 350 000 ₽
Теперь создадим библиотеку Greeting также без особенностей Java 9, чтобы посмотреть, как это работает.
Создадим файл greeting/ser/lib/Greeting.java со следующим кодом:
Изменим класс Main для использования нашей библиотеки:
Скомпилируем эту библиотеку:
Чтобы показать, как работают оригинальные Java-библиотеки, мы превратим эту библиотеку в jar-файл без дескрипторов модулей Java 9:
Команда создаст файл libs/lib.jar , содержащий класс lib.Greeting .
Просмотреть информацию о jar-файле можно с помощью опции tf :
Команда должна вывести:
Теперь для компиляция app.Main нам необходимо указать компилятору, где найти класс lib.Greeting .
Используем для этого cp (classpath):
И то же самое для запуска программы:
Мы можем упаковать приложение в jar-файл:
И затем запустить его:
Вот так выглядит структура нашего проекта на данный момент:
Модуляризация проекта
Пока что ничего нового, но давайте начнем модуляризацию нашего проекта. Для этого создадим модульный дескриптор (всегда называется module-info.java и размещается в корневой директории src/ ):
Команда для компиляции модуля в Java 9 отличается от того, что мы видели раньше. Использование старой команды с добавлением модуля к списку файлов приводит к ошибке:
Чтобы понять, почему наш код не компилируется, необходимо понять, что такое безымянные модули.
Любой класс, который загружается не из именованного модуля, автоматически выполняет часть безымянного модуля. В примере выше перед созданием модульного дескриптора наш код не был частью какого-либо модуля, следовательно, он был ассоциирован с безымянным модулем. Безымянный модуль — это механизм совместимости. Проще говоря, это позволяет разработчику использовать в приложениях Java 9 код, который не был модуляризирован. По этой причине код, относящийся к безымянному модулю, имеет правила сродни Java 8 и ранее: он может видеть все пакеты, экспортируемые из других модулей, и все пакеты безымянного модуля.
Когда модульный дескриптор добавляется к модулю, его код больше не является частью безымянного модуля и не может видеть код других модулей, пока не импортирует их. В случае выше модуль com.app не требует никаких модулей, поэтому модуль библиотеки Greeting для него не виден. Он может видеть только пакеты модуля java.base .
Модули в Java 9, за исключением неуловимого безымянного модуля описанного выше, должны объявлять, какие другие модули им необходимы. В случае с модулем com.app единственным требованием является библиотека Greeting. Но, как вы могли догадаться, эта библиотека (как и другие библиотеки, не поддерживающие Java 9) не является модулем Java 9. Как же нам включить её в проект?
В таком случае вам нужно знать имя jar-файла. Если у вас есть зависимость от библиотеки, которая не была конвертирована в модуль Java 9, вам надо знать, какой jar-файл вызывается для этой библиотеки, потому что Java 9 переведёт имя файла в валидный модуль.
Это называется автоматический модуль.
Так же, как и безымянные модули, автоматические модули могут читать из других модулей, и все их пакеты являются экспортируемыми. Но, в отличие от безымянных модулей, на автоматические можно ссылаться из явных модулей.
Чтобы узнать имя автоматического модуля, компилятор конвертирует неальфанумерические, поэтому что-то вроде slf4j-api-1.7.25.jar превратится в имя модуля sl4j.api .
У нас есть библиотека с именем lib.jar . Давайте переименуем jar-файл в greetings-1.0.jar :
Это более стандартное имя файла, и теперь мы можем сказать Java включить автоматический модуль с приемлемым именем greetings . И можем вызывать его из com.app модуля:
Модули не добавлены в classpath . Как и обычные jar-файлы, они используют новый флаг --module-path (-p) . Теперь мы можем скомпилировать наши модули следующей командой:
Чтобы запустить app.Main командой java мы можем использовать новый флаг --module (-m) , который принимает либо имя модуля, либо шаблон module-name/main-class :
И мы получим вывод Hi, there .
Для создания и использования app.jar в качестве исполняемого jar-файла выполните следующие команды:
Следующим шагом будет модуляризация библиотек, которые используются нашим приложением.
Модуляризация библиотек
Для модуляризации библиотеки нельзя сделать ничего лучше, чем использовать jdeps — инструмент для статистического анализа, который является частью Java SE.
Например, команда, которая позволяет увидеть зависимости нашей небольшой библиотеки, выглядит так:
А вот результат её выполнения:
Как и ожидалось, библиотека зависит только от java.base модуля.
Мы знаем, что com.app зависит от модуля greetings . Давайте попробуем использовать jdeps , чтобы он подтвердил нам это. Для этого нужно удалить файлы module-info.calss и app.jar и затем запустить jdeps :
Хорошо, но можно лучше. Мы можем попросить jdeps автоматически сгенерировать модульный дескриптор для набора jar-файлов. Просто укажите ему, куда сохранять сгенерированные файлы (например, в папку generated-mods ), и где находятся jar-файлы:
Команда создаст два файла: generated-mods/app/module-info.java и generated-mods/greetings/module-info.java со следующим содержимым:
Теперь мы можем добавить сгенерированный дескриптор для нашей библиотеки в её исходный код, переупаковать её, и у нас получится полностью модульное приложение:
Теперь у нас есть полностью модуляризированные библиотека и приложение. После удаления сгенерированных и бинарных файлов, структура нашего приложения выглядит следующим образом:
Обратите внимание, что для получения хороших данных от jdeps вы должны предоставить местоположение всех jar-файлов, которые используются в приложении, чтобы он мог составить полный граф модуля.
Наиболее простым способом получить список всех jar-файлов, которые используются в библиотеке, является использование скрипта Gradle. Он выведет пути локальных jar-файлов для всех зависимостей библиотек, которые вы добавите в секцию зависимостей, и скачает их, если необходимо:
Если у вас нет Gradle, вы можете использовать SdkMAN! для его установки:
Для получения списка зависимостей используйте следующую команду:
Полученную информацию передайте jdeps для анализа и автоматической генерации метаданных.
Это файл, который jdeps выводит для javaslang.match :
Создание собственного образа среды выполнения
С помощью jlink Java-приложения могут распространяться как образы, которые не требуют установки JVM.
Следующая команда создает образ для нашего com.app модуля без оптимизации, сжатия или отладочной информации:
Меньший размер может быть достигнут использованием некоторых флагов jlink , таких как --strip-debug и --compress :
Размер пакетов можно посмотреть с помощью команды du -sh :
Для запуска приложения используйте предоставляемый лаунчер в директории bin :
На этом всё. Разбор нововведений в Java 9 предлагаем прочитать в нашей статье.
Читайте также: