Есть ли способ добавить maven-зависимости при использовании maven-jlink-plugin?
Я использую этот проект Github, чтобы познакомиться с новыми модульными функциями в Java 9. Я хотел бы добавить зависимости в проект и иметь возможность создавать собственный образ. Однако, когда я пытаюсь добавить новую зависимость в pom.xml и добавить инструкцию require в module-info.java, я получаю следующую ошибку из maven-jlink-plugin:
Error: module-info.class not found for joda.time module
Я пытаюсь использовать это как подтверждение концепции, что я могу развернуть образы, используя новую фазу связывания, но, естественно, мне нужно иметь возможность иметь внешние зависимости и мне нужно использовать maven (ограничение работы).
Изменения в mod-jar/pom.xml
...
<dependencies>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.9</version>
</dependency>
</dependencies>
...
мод-банка /module-info.java
module com.soebes.nine.jar {
requires java.base;
requires joda.time;
exports com.soebes.example.nine.jar;
}
Журналы:
[INFO] --- maven-jlink-plugin:3.0.0-alpha-1:jlink (default-jlink) @ mod-jlink ---
[INFO] Toolchain in maven-jlink-plugin: jlink [ /Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/jlink ]
[INFO] The following dependencies will be linked into the runtime image:
[INFO] -> module: com.soebes.nine.one ( /Users/sebastianrestrepo/Projects/jdk9-jlink-jmod-example/maven-example/mod-1/target/jmods/com.soebes.nine.one.jmod )
[INFO] -> module: com.soebes.nine.two ( /Users/sebastianrestrepo/Projects/jdk9-jlink-jmod-example/maven-example/mod-2/target/jmods/com.soebes.nine.two.jmod )
[INFO] -> module: com.soebes.nine.jar ( /Users/sebastianrestrepo/Projects/jdk9-jlink-jmod-example/maven-example/mod-jar/target/com.soebes.nine.jar-1.0-SNAPSHOT.jar )
[INFO] -> module: joda.time ( /Users/sebastianrestrepo/.m2/repository/joda-time/joda-time/2.9.9/joda-time-2.9.9.jar )
[ERROR]
Error: module-info.class not found for joda.time module
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] parent ............................................. SUCCESS [ 1.460 s]
[INFO] com.soebes.nine.one ................................ SUCCESS [ 2.022 s]
[INFO] com.soebes.nine.two ................................ SUCCESS [ 1.392 s]
[INFO] com.soebes.nine.jar ................................ SUCCESS [ 1.388 s]
[INFO] mod-jlink .......................................... FAILURE [ 1.061 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.911 s
[INFO] Finished at: 2017-11-03T15:27:35-04:00
[INFO] Final Memory: 26M/981M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-jlink-plugin:3.0.0-alpha-1:jlink (default-jlink) on project mod-jlink:
Я был бы очень признателен за любую помощь. Благодарю.
4 ответа
Это не имеет ничего общего с плагином, я верю. модуль joda.time
в твоем случае кажется автоматическим модулем.
jlink
Инструмент не поддерживает связывание автоматических модулей, потому что они могут полагаться на произвольное содержимое пути к классам, что противоречит идее автономной среды выполнения Java.
Таким образом, есть два способа исправить это: -
(у вас нет баночки) Временно создайте
module-info.java
[Вы могли бы использоватьjdeps
инструмент для него] и обновить банку [используяjar
tool] с соответствующим скомпилированным классом, как в проектах под Java 9.(у вас есть зависимость) Постоянно переносите jar в Java 9, где он будет состоять из
module-info.class
сам по себе после компиляции и упаковки.
Вы можете использовать плагин ModiTect Maven, чтобы добавить дескриптор модуля в JAR и создать модульный образ среды выполнения с этим модулем.
Отказ от ответственности: я автор ModiTect.
У меня была похожая проблема в одном из моих проектов. Сначала я попробовал
moditect-maven-plugin
, которая отлично сработала! Однако с помощью этого плагина вам необходимо отдельно настроить каждую зависимость, в которой отсутствует дескриптор модуля. Если у вас есть много зависимостей, в которых отсутствует дескриптор модуля, это может стать громоздким.
Поэтому я решил разработать новый плагин maven,
jigsaw-maven-plugin
(см. ). Плагин обеспечивает три цели: исправление всех безымянных модулей (см. Шаг 3), а также связывание и упаковку этих модулей (см. Шаги 4 и 5) .
Перед установкой исправлений, компоновкой и упаковкой вам необходимо собрать проект JAR (см. Шаг 1) и скопировать зависимости проекта (см. Шаг 2) в общее место (например,
${project.build.directory}/modules
). Возможно, вы можете использовать следующие конфигурации плагинов сборки, чтобы начать работу (подробнее см. На https://github.com/ghackenberg/jigsaw-maven-pluginстранице GitHub ):
Шаг 1. Создайте архив
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<outputDirectory>${project.build.directory}/modules</outputDirectory>
</configuration>
</plugin>
Шаг 2. Скопируйте зависимости
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/modules</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Шаг 3. Исправьте все неназванные модули
Искать JAR в
modulePath
отсутствует дескриптор модуля, сгенерируйте недостающие дескрипторы модуля, используя
jdeps
а также
javac
, и добавьте их в соответствующие JAR-файлы, используя
java.util.zip
.
<plugin>
<groupId>io.github.ghackenberg</groupId>
<artifactId>jigsaw-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>patch</goal>
</goals>
<configuration>
<modulePath>${project.build.directory}/modules</modulePath>
</configuration>
</execution>
</executions>
</plugin>
Шаг 4. Свяжите модули
Свяжите модули с помощью
jlink
.
<plugin>
<groupId>io.github.ghackenberg</groupId>
<artifactId>jigsaw-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>link</goal>
</goals>
<configuration>
<modulePath>${project.build.directory}/modules</modulePath>
<module>your.module.name</module>
<output>${project.build.directory}/image</output>
</configuration>
</execution>
</executions>
</plugin>
Шаг 5: Модули пакета
Модули пакета, использующие
jpackage
.
<plugin>
<groupId>io.github.ghackenberg</groupId>
<artifactId>jigsaw-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>package</goal>
</goals>
<configuration>
<modulePath>${project.build.directory}/modules</modulePath>
<runtimeImage>${project.build.directory}/image</runtimeImage>
<mainClass>your.module.name/your.package.Main</mainClass>
</configuration>
</execution>
</executions>
</plugin>
Позвольте мне попытаться объяснить технические основы этого:
joda-time в версии 2.9.9, как указано в вопросе, является немодулярным jar-файлом, он не содержит module-info.class и не объявляет себя автоматическим модулем с использованием Automatic-Module-Name: in его META-INF/MANIFEST.MF
Классы в реальном модуле не могут вызывать классы на пути к классам, поэтому вы не можете использовать "require jode.time" в вашем модуле-info с этой версией.
Автоматические модули могут использовать классы на ClassPath. Чтобы использовать классы из немодульного фляги в реальном модуле, вы можете использовать обертку, которая сама является автоматическим модулем.
К настоящему времени существует версия 2.10.1 joda-time, которая является автоматическим модулем и объявляет "Automatic-Module-Name: org.joda.time", таким образом, вы можете использовать "require org.joda.time" в своем настоящий модуль с этой новой версией.
Теперь новый инструмент jlink не может работать напрямую с немодулярными банками или автоматическими банками, и плагин maven-jlink в настоящее время является просто оболочкой maven вокруг инструмента jlink, переводя свои параметры конфигурации в аргументы для инструмента jlink.
Чтобы создать пользовательскую среду выполнения Java для проектов, использующих смешанные зависимости maven с реальными модулями, автоматическими модулями и немодульными банками, вы должны знать все зависимости системных модулей ваших реальных модулей, автоматических модулей и немодульных банок и использовать их. параметр --add-modules, чтобы связать с ними.
Чтобы собрать зависимости системного модуля, вы можете использовать новый инструмент jdeps с параметром --print-module-deps или --list-deps в зависимости от используемой версии JDK.
Если вы используете maven для своего проекта, вы можете автоматизировать эту задачу, создав или используя плагин maven, который сделает это за вас.