[Из песочницы] Maven плагин для JPackage из Java 14
Добрый день!
Не так давно вышла новая Java 14. Среди многих интересных фич меня заинтересовала одна, а именно упаковщик jpackage (пока в инкубаторе).
Смысл этой фичи в том, чтоб взять наше приложение, все зависимости и рантайм, и собрать один установочный файл, который легко распространять, устанавливать и запускать.
Описание, как пользоваться инструментом, есть в статье.
Поиграв с упаковщиком, мне захотелось попробовать внедрить его на своем pet-проекте. Так проект написан с использованием Maven, то было решено написать плагин. Так как я впервый раз пишу плагин для Maven, то эта задача стала для меня вдвойне интересней.
После гугления на тему плагинов стало ясно, что писать их не сложно: отнаследовался от класса AbstractMojo, реализовал метод void execute (), повесил аннотацию Mojo и плагин готов.
В результате получилась вот такая заготовка:
@Mojo(name = "createpackage", defaultPhase = LifecyclePhase.VALIDATE, threadSafe =true)
public class JpackageMojo extends AbstractMojo {
@Override
public void execute() {
//Тут можно писать что угодно.
}
}
«createpackage» — имя цели;
«LifecyclePhase.VERIFY» — будет выполняться на верификации.
Чтоб собрать .exe установщика необходимо выполнить команду:
jpackage --name myapp --input lib --main-jar main.jar
То есть надо задать имя файла на выходе, папку с приложением и указать джарник с методом main. Для получения этих данных добавим в класс следующие строки:
@Parameter(defaultValue = "${project.build.directory}")
private File buildDirectory;
@Parameter( defaultValue = "${project}", readonly = true )
private MavenProject project;
В документации написано, что инструмент доступен через java.util.spi.ToolProvider.findFirst («jpackage»), но у меня не получилось его использовать. Возможно это связано с тем, что jpackage находится в инкубаторе. Если кто то знает решение, то прошу поделиться в комментариях.
Ну раз не получается сделать красиво, то будем делать некрасиво, через Runtime.getRuntime ().exec (command). Для упрощения, я предположил, что jpackage.exe добавлено в переменные окружения среды.
Получившаяся команда для выполнения:
jpackage.exe --name name --input path --main-jar main --dest dest --win-menu --win-shortcut
где добавлено еще пару флагов: --dest dest указывает место для результата, --win-menu--win-shortcut добавляет ссылки в меня и на рабочем столе в Windows.
В результате у меня получилось следующее:
@Mojo(name = "createpackage", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true)
public class JpackageMojo extends AbstractMojo {
public static final String ERROR_CREATE_PACKAGE = "Error create package";
@Parameter(defaultValue = "${project.build.directory}")
private File buildDirectory;
@Parameter( defaultValue = "${project}", readonly = true )
private MavenProject project;
@Override
public void execute() {
var name = project.getArtifactId();
var path = buildDirectory.getPath();
var main = project.getArtifact().getFile().getName();
var dest = path + "\\dest";
try {
String command = "jpackage.exe --name " + name + " --input "
+ path + " --main-jar " + main + " --dest " + dest
+ " --win-menu --win-shortcut";
getLog().debug(command);
Process proc = Runtime.getRuntime().exec(command);
getLog().info(Arrays.toString(proc.getInputStream().readAllBytes()));
proc.waitFor();
proc.destroy();
} catch (IOException e) {
getLog().error(ERROR_CREATE_PACKAGE, e);
} catch (InterruptedException e) {
getLog().error(ERROR_CREATE_PACKAGE, e);
Thread.currentThread().interrupt();
}
}
}
В проекте можно подключить путем добавления следующих строк в pom.xml
org.sterzhen
jpackage-maven-plugin
1.0-SNAPSHOT
createpackage
При испытании плагина на pet-проекте ждала еще одна неожиданность, а именно что для работы упаковщика в среде Windows необходимо дополнительно установить WiX 3.0 или более позднюю версию.
После установки WiX плагин заработал, чем принес мне радость маленькой победы. Да, пока он примитивный и работает только для винды, но это только начало.
Буду рад услышать замечания и пожелания.
Исходный код можно найти по ссылке.
Документация:
http://openjdk.java.net/jeps/343
https://docs.oracle.com/en/java/javase/14/docs/specs/man/jpackage.html
https://docs.oracle.com/en/java/javase/14/jpackage/packaging-overview.htm
Спасибо!