JEP 343: Packaging Tool (Incubator)
Инструмент упаковки в статусе Incubator (инкубационный модуль)
| Ответственный | Kevin Rushforth |
| Тип | Feature |
| Область | JDK |
| Статус | Closed / Delivered |
| Выпуск | 14 |
| Компонент | tools / jpackage |
| Обсуждение | core dash libs dash dev at openjdk dot java dot net |
| Трудоёмкость | M |
| Длительность | M |
| Связан с | JEP 311: Java Packager API & CLI |
| JEP 392: Packaging Tool | |
| Рецензенты | Alan Bateman, Alexander Matveev, Alexey Semenyuk, Andy Herrick, Mandy Chung, William Harnois |
| Одобрен | Brian Goetz |
| Создан | 2018/04/04 19:22 |
| Обновлён | 2021/08/28 00:10 |
| Задача | 8200758 |
Аннотация
Создать инструмент для упаковки автономных Java-приложений.
Цели
Создать простой инструмент упаковки на основе инструмента 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) не будет.
- Механизма автоматического обновления не будет.
- Инструмент не будет доступен в Solaris.
Мотивация
Многие Java-приложения нужно устанавливать на нативную платформу полноценно, а не просто помещать в class path или module path. Разработчику приложения недостаточно поставить простой JAR-файл: он должен поставить устанавливаемый пакет, подходящий для нативной платформы. Так Java-приложения можно распространять, устанавливать и удалять привычным для пользователей способом. Например, в Windows пользователи ожидают, что смогут установить программу двойным щелчком по пакету, а затем удалить её через панель управления; в macOS пользователи ожидают, что смогут дважды щёлкнуть по DMG-файлу и перетащить приложение в папку Applications.
Инструмент упаковки также может помочь закрыть пробелы, оставшиеся после других технологий, например Java Web Start, удалённого из JDK 11 от Oracle, и pack200, который в JDK 11 получил статус Deprecated for Removal (устаревший, будет удалён) с удалением в одном из будущих выпусков. Разработчики могут с помощью 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. Чтобы запустить приложение, лаунчер поместит в class path JVM каждый JAR-файл, скопированный из входного каталога.
Если вы хотите создать пакет в формате, отличном от формата по умолчанию, используйте параметр --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 <version>--copyright <string>--description <string>--license-file <file>--name <string>--vendor <string>
Инструмент использует аргументы этих параметров так, как это принято для данного типа пакета. Параметры метаданных пакета для конкретных платформ описаны ниже.
Ассоциации файлов
Для приложения можно задать одну или несколько ассоциаций с типами файлов с помощью параметра --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предоставляет приложениям из class path в безымянном модуле. -
Для модульного приложения из модульных JAR-файлов и/или файлов JMOD образ среды выполнения содержит главный модуль приложения и транзитивное замыкание всех его зависимостей. В него войдут не все доступные поставщики сервисов; если вы хотите, чтобы они были связаны, укажите параметр
--bind-servicesинструментаjpackage.
В обоих случаях, если в образ среды выполнения нужно добавить дополнительные модули, можно использовать параметр --add-modules инструмента jpackage. Список модулей в образе среды выполнения находится в файле release образа.
Образы среды выполнения, созданные инструментом jpackage, не содержат отладочных символов, обычных команд JDK, man-страниц и файла 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
Особенности платформ
В этом разделе описаны особенности инструмента jpackage на разных платформах, в том числе структура образов приложений и параметры для конкретных платформ. Команда jpackage --help выводит сводку по всем параметрам.
Образы приложений, созданные инструментом jpackage, содержат некоторые файлы, не показанные в приведённых ниже структурах; такие файлы следует считать деталями реализации, которые могут измениться.
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.
Параметры для Linux:
--linux-package-name <package name>— имя пакета для Linux, по умолчанию совпадает с именем приложения--linux-deb-maintainer <email address>— сопровождающий (maintainer) DEB-пакета--linux-menu-group <menu-group-name>— группа меню, в которую помещается приложение--linux-package-deps <deps>— пакеты или возможности, необходимые приложению--linux-rpm-license-type <type string>— тип лицензии (License: <value>файла RPM.spec)--linux-app-release <release value>— значение Release файла RPM<name>.specили значение Debian revision управляющего файла DEB--linux-app-category <category value>— значение Group файла RPM<name>.specили значение Section управляющего файла DEB--linux-shortcutСоздаёт ярлык для приложения
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.
Параметры, специфичные для macOS:
--mac-package-identifier <string>— идентификатор, однозначно определяющий приложение для macOS (по умолчанию имя главного класса; допускаются только буквы, цифры, дефис и точка)--mac-package-name <string>— имя приложения в строке меню (по умолчанию имя приложения; должно быть короче 16 символов и подходить для отображения в строке меню и в окне сведений о приложении Info)--mac-package-signing-prefix <string>— при подписании пакета приложения (bundle) значение, добавляемое в начало идентификаторов всех компонентов, которые нужно подписать, но у которых ещё нет идентификатора bundle--mac-sign— запросить подписание пакета (bundle)--mac-signing-keychain <file>— путь к связке ключей (keychain), в которой ищется идентификатор для подписи (по умолчанию стандартные связки ключей)--mac-signing-key-user-name <team name>— часть идентификатора подписи Apple с названием команды (например, «Developer ID Application: »)
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.
Параметры, специфичные для Windows:
--win-console— создаёт консольный лаунчер для приложения (следует указывать для приложений, которым требуется взаимодействие через консоль)--win-dir-chooser— добавляет диалог, в котором пользователь может выбрать каталог для установки приложения--win-menu— добавляет приложение в системное меню--win-menu-group <menu-group-name>— группа меню «Пуск», в которую помещается приложение--win-per-user-install— установить приложение для отдельного пользователя--win-shortcut— создать ярлык приложения на рабочем столе--win-upgrade-uuid <string>— UUID, связанный с обновлениями этого пакета
Поставка jpackage
Инструмент jpackage будет поставляться в JDK как Incubator-модуль с именем jdk.incubator.jpackage. Поскольку эта возможность поставляется в Incubator-модуле, стабильность параметров командной строки, структуры приложения и других экспортируемых интерфейсов инструмента jpackage не гарантируется, и они могут быть пересмотрены в будущем выпуске. При запуске из командной строки инструмент будет выводить предупреждение. Модуль jdk.incubator.jpackage не будет разрешаться по умолчанию, а при его разрешении будет выводиться предупреждение.
Инструмент jpackage основан на инструменте javapackager, из которого удалены все возможности, связанные с Java Web Start и JavaFX. Интерфейс командной строки (CLI) соответствует JEP 293 (Guidelines for JDK Command-Line Tool Options). Помимо интерфейса командной строки, jpackage доступен через ToolProvider API (java.util.spi.ToolProvider) под именем "jpackage".
Тестирование
Большую часть тестов можно выполнить автоматизированными скриптами, но нужно учитывать несколько моментов:
-
Для тестирования нативных пакетов может потребоваться установка дополнительных инструментов; такие тесты нужно писать так, чтобы они пропускались в системах, где нужных инструментов нет.
-
Проверка некоторых типов нативных пакетов (например,
exeв Windows илиdmgв macOS) может потребовать ручного тестирования. -
Нам нужно убедиться, что нативные пакеты устанавливаются и удаляются чисто, чтобы разработчики могли тестировать в своём локальном окружении, не опасаясь засорить свои системы.
Зависимости
Нативные пакеты будут создаваться с помощью инструментов целевой платформы. Для Windows есть дополнительный инструмент, который разработчикам нужно будет установить, если они хотят создавать нативные пакеты:
- Для создания пакетов
msiилиexeтребуется Wix — сторонний инструмент
Ведётся работа над улучшением jlink, чтобы в будущей версии JDK он мог создавать нативные лаунчеры. Может потребоваться определённая координация между jlink и jpackage.