[Из песочницы] Maven плагин для JPackage из Java 14

?v=1

Добрый день!

Не так давно вышла новая 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

Спасибо!

© Habrahabr.ru