JEP 392: Packaging Tool
Инструмент упаковки приложений
| Ответственный | Andy Herrick |
| Тип | Feature |
| Область | JDK |
| Статус | Closed / Delivered |
| Выпуск | 16 |
| Компонент | tools / jpackage |
| Обсуждение | core dash libs dash dev at openjdk dot java dot net |
| Трудоёмкость | S |
| Длительность | S |
| Связан с | JEP 343: Packaging Tool (Incubator) |
| Рецензенты | Alexander Matveev, Alexey Semenyuk, Kevin Rushforth, Philip Race |
| Одобрен | Brian Goetz |
| Создан | 2020/06/17 14:57 |
| Обновлён | 2021/02/19 20:03 |
| Задача | 8247768 |
Аннотация
Предоставить инструмент jpackage для упаковки автономных Java-приложений.
История
Инструмент jpackage появился в JDK 14 в статусе Incubator (инкубационный модуль) в рамках JEP 343. В JDK 15 он остался в статусе Incubator, чтобы было время собрать дополнительные отзывы. Теперь он готов выйти из статуса Incubator и стать возможностью, готовой к промышленному использованию. Вследствие этого перехода имя модуля jpackage изменится с jdk.incubator.jpackage на jdk.jpackage.
Единственное существенное изменение по сравнению с JEP 343 состоит в том, что мы заменили параметр --bind-services более общим параметром --jlink-options, описанным ниже.
Цели
Создать инструмент упаковки на основе устаревшего инструмента JavaFX javapackager, который:
-
Поддерживает нативные форматы пакетов, чтобы конечные пользователи устанавливали приложения привычным для них способом. К этим форматам относятся
msiиexeв Windows,pkgиdmgв macOS,debиrpmв Linux. -
Позволяет задавать параметры запуска на этапе упаковки.
-
Может вызываться напрямую из командной строки или программно через API
ToolProvider.
Что не является целью
- Следующие возможности устаревшего инструмента
javapackagerне поддерживаются:- поддержка приложений Java Web Start,
- возможности, специфичные для JavaFX,
- использование
jdepsдля определения необходимых модулей и - плагин для Ant.
-
Графического интерфейса у инструмента нет: достаточно интерфейса командной строки (CLI).
-
Кросс-компиляция не поддерживается. Например, чтобы создать пакеты для Windows, инструмент нужно запускать в Windows. Инструмент упаковки будет зависеть от платформенно-специфичных инструментов.
-
Особой поддержки юридических файлов, помимо той, что уже есть в файлах JMOD, нет. Объединения отдельных файлов лицензий не будет.
-
Нативная заставка при запуске (splash screen) не поддерживается.
-
Механизма автоматического обновления нет.
Мотивация
Многие Java-приложения нужно устанавливать на нативные платформы полноценно, а не просто помещать в путь к классам (class path) или путь к модулям (module path). Разработчику приложения недостаточно поставить простой JAR-файл: он должен поставить устанавливаемый пакет, подходящий для нативной платформы. Так Java-приложения можно распространять, устанавливать и удалять привычным для пользователей способом. Например, пользователи Windows ожидают, что смогут установить программу двойным щелчком по пакету, а затем удалить её через панель управления; пользователи macOS ожидают, что смогут дважды щёлкнуть по DMG-файлу и перетащить приложение в папку Application.
Инструмент jpackage также может помочь восполнить пробелы, оставшиеся после прежних технологий, таких как Java Web Start, удалённая из JDK 11 от Oracle, и pack200, удалённый в JDK 14 (JEP 367). Разработчики могут с помощью jlink урезать JDK до минимального набора необходимых модулей, а затем с помощью инструмента упаковки создать сжатый устанавливаемый образ, который можно развернуть на целевых машинах.
Раньше для решения этих задач вместе с JDK 8 от Oracle поставлялся инструмент упаковки javapackager. Однако он был удалён из JDK 11 от Oracle вместе с удалением JavaFX.
Описание
Инструмент jpackage упаковывает Java-приложение в платформенно-специфичный пакет, который включает все необходимые зависимости. Приложение может быть предоставлено как набор обычных JAR-файлов или как набор модулей. Поддерживаются следующие платформенно-специфичные форматы пакетов:
- Linux:
debиrpm - macOS:
pkgиdmg - Windows:
msiиexe
По умолчанию jpackage создаёт пакет в формате, наиболее подходящем для системы, в которой он запущен.
Базовое использование: немодульные приложения
Предположим, у вас есть приложение из JAR-файлов, которые лежат в каталоге lib, и lib/main.jar содержит главный класс. Тогда команда
$ jpackage --name myapp --input lib --main-jar main.jar
упакует приложение в формате, используемом по умолчанию в локальной системе, и оставит итоговый файл пакета в текущем каталоге. Если в файле MANIFEST.MF в main.jar нет атрибута Main-Class, главный класс нужно указать явно:
$ jpackage --name myapp --input lib --main-jar main.jar \
--main-class myapp.Main
Пакет будет называться myapp, хотя имя самого файла пакета будет длиннее и будет заканчиваться типом пакета (например, myapp.exe). Пакет будет включать лаунчер приложения, который тоже называется myapp. Чтобы запустить приложение, лаунчер поместит каждый JAR-файл, скопированный из входного каталога, в путь к классам JVM.
Если нужно создать пакет в формате, отличном от формата по умолчанию, используйте параметр --type. Например, чтобы создать в macOS файл pkg, а не dmg:
$ jpackage --name myapp --input lib --main-jar main.jar --type pkg
Базовое использование: модульные приложения
Если у вас модульное приложение, состоящее из модульных JAR-файлов и/или файлов JMOD в каталоге lib, а главный класс находится в модуле myapp, то команда
$ jpackage --name myapp --module-path lib -m myapp
упакует его. Если модуль myapp не указывает свой главный класс, его, опять же, нужно указать явно:
$ jpackage --name myapp --module-path lib -m myapp/myapp.Main
(При создании модульного JAR-файла или файла JMOD главный класс можно указать с помощью параметра --main-class инструментов jar и jmod.)
Метаданные пакета
Инструмент jpackage позволяет задавать различные платформенно-независимые метаданные, такие как имя и версия приложения (app-version), а также платформенно-специфичные метаданные для каждой платформы.
Описание всех параметров jpackage приведено на странице руководства (man page) jpackage.
Ассоциации файлов
Для приложения можно определить одну или несколько ассоциаций с типами файлов с помощью параметра --file-associations, который можно указывать несколько раз. Аргумент этого параметра — файл свойств со значениями для одного или нескольких из следующих ключей:
extensionзадаёт расширение файлов, которые будут связаны с приложением,mime-typeзадаёт MIME-тип файлов, которые будут связаны с приложением,iconзадаёт значок внутри образа приложения, используемый для этой ассоциации, иdescriptionзадаёт краткое описание ассоциации.
Лаунчеры
По умолчанию инструмент jpackage создаёт для приложения простой нативный лаунчер. Лаунчер по умолчанию можно настроить с помощью следующих параметров:
--arguments <string>— аргументы командной строки, передаваемые главному классу, если лаунчеру не переданы аргументы командной строки (этот параметр можно указывать несколько раз)--java-options <string>— параметры, передаваемые JVM (этот параметр можно указывать несколько раз)
Если приложению нужны дополнительные лаунчеры, их можно добавить с помощью параметра --add-launcher:
--add-launcher <launcher-name>=<file>
Указанный <file> должен быть файлом свойств со значениями для одного или нескольких ключей app-version icon arguments java-options main-class main-jar module или win-console. Значения этих ключей будут интерпретироваться как аргументы одноимённых параметров, но применительно к создаваемому лаунчеру, а не к лаунчеру по умолчанию. Параметр --add-launcher можно указывать несколько раз.
Образы приложений
Инструмент jpackage строит образ приложения, который служит входными данными для платформенно-специфичного инструмента упаковки, вызываемого на последнем шаге. Обычно этот образ является временным артефактом, но иногда его нужно настроить перед упаковкой. Поэтому инструмент jpackage можно запускать в два шага. Сначала создайте исходный образ приложения со специальным типом пакета app-image:
$ jpackage --name myapp --module-path lib -m myapp --type app-image
В результате в каталоге myapp будет создан образ приложения. Настройте этот образ так, как нужно, а затем создайте итоговый пакет с помощью параметра --app-image:
$ jpackage --name myapp --app-image myapp
Образы среды выполнения
Образ приложения содержит как файлы, из которых состоит ваше приложение, так и образ среды выполнения JDK, в котором будет работать приложение. По умолчанию инструмент jpackage вызывает инструмент jlink, чтобы создать образ среды выполнения. Содержимое образа зависит от типа приложения:
-
Для немодульного приложения из JAR-файлов образ среды выполнения содержит тот же набор модулей JDK, который обычный лаунчер
javaпредоставляет приложениям, работающим через путь к классам, в безымянном модуле. -
Для модульного приложения из модульных JAR-файлов и/или файлов JMOD образ среды выполнения содержит главный модуль приложения и транзитивное замыкание всех его зависимостей.
Набор параметров jlink, используемый jpackage по умолчанию:
--strip-native-commands --strip-debug --no-man-pages --no-header-files
но его можно изменить с помощью параметра --jlink-options. Итоговый образ не будет включать всех доступных поставщиков сервисов; если нужно их связать, используйте --jlink-options и включите --bind-services в список параметров jlink.
В обоих случаях, если в образ среды выполнения нужно включить дополнительные модули, можно использовать параметр --add-modules инструмента jpackage. Список модулей в образе среды выполнения приведён в файле release этого образа.
Образы среды выполнения, созданные инструментом jpackage, не содержат файла src.zip.
Если нужно дополнительно настроить образ среды выполнения, можно самостоятельно вызвать jlink и передать полученный образ инструменту jpackage через параметр --runtime-image. Например, если с помощью инструмента jdeps вы определили, что вашему немодульному приложению нужны только модули java.base и java.sql, размер пакета можно существенно уменьшить:
$ jlink --add-modules java.base,java.sql --output myjre
$ jpackage --name myapp --input lib --main-jar main.jar --runtime-image myjre
Структура и содержимое образа приложения
Структура и содержимое образов приложений зависят от платформы. Реальные образы содержат некоторые файлы, не показанные в приведённых ниже структурах; такие файлы являются деталями реализации и могут измениться в любой момент.
Linux
myapp/
bin/ // Application launcher(s)
myapp
lib/
app/
myapp.cfg // Configuration info, created by jpackage
myapp.jar // JAR files, copied from the --input directory
mylib.jar
...
runtime/ // JDK runtime image
Каталог установки по умолчанию в Linux — /opt. Его можно переопределить с помощью параметра --install-dir.
macOS
MyApp.app/
Contents/
Info.plist
MacOS/ // Application launcher(s)
MyApp
Resources/ // Icons, etc.
app/
MyApp.cfg // Configuration info, created by jpackage
myapp.jar // JAR files, copied from the --input directory
mylib.jar
...
runtime/ // JDK runtime image
Каталог установки по умолчанию в macOS — /Applications. Его можно переопределить с помощью параметра --install-dir.
Windows
MyApp/
MyApp.exe // Application launcher(s)
app/
MyApp.cfg // Configuration info, created by jpackage
myapp.jar // JAR files, copied from the --input directory
mylib.jar
...
runtime/ // JDK runtime image
Каталог установки по умолчанию в Windows — C:\Program Files\. Его можно переопределить с помощью параметра --install-dir.
Поставка jpackage
Инструмент jpackage поставляется в составе JDK в модуле с именем jdk.jpackage.
Интерфейс командной строки соответствует JEP 293 (Guidelines for JDK Command-Line Tool Options).
Помимо интерфейса командной строки, jpackage доступен через ToolProvider API (java.util.spi.ToolProvider) под именем "jpackage".
Тестирование
Большинство тестов можно выполнять с помощью автоматизированных скриптов, но нужно учитывать несколько особенностей:
-
Для тестирования нативных пакетов может потребоваться установка дополнительных инструментов; такие тесты нужно будет писать так, чтобы они пропускались в системах, где нужных инструментов нет.
-
Проверка некоторых типов нативных пакетов (например,
exeв Windows илиdmgв macOS) может потребовать ручного тестирования. -
Мы должны гарантировать, что нативные пакеты устанавливаются и удаляются без следов, чтобы разработчики могли тестировать их в своём локальном окружении, не опасаясь засорить свои системы.
Зависимости
Нативные пакеты создаются с помощью инструментов, доступных на хост-платформе. В Windows разработчикам нужно установить сторонний инструмент «Wix», чтобы создавать пакеты msi или exe.