在使用maven-jlink-plugin时,有没有办法添加maven依赖项?

v2g6jxz6  于 2022-12-03  发布在  Maven
关注(0)|答案(4)|浏览(261)

我使用这个Github project来展示Java 9中新的模块化特性。我想给项目添加依赖项,并能够构建一个原生映像。但是,当我试图给pom.xml添加一个新的依赖项,并给www.example.com添加requires语句时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>
...

mod-jar/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:

我真的很感激你的帮助。谢谢。

798qvoo8

798qvoo81#

我相信这与插件没有太大关系。模块joda.time在你的情况下似乎是一个 * 自动模块 *。
jlink tool does not support linking of automatic modules,因为它们可以依赖于类路径的任意内容,这与自包含Java运行时的理念背道而驰。
所以有两种方法来解决这个问题:-

  • (您并不拥有这个jar)暂时创建一个module-info.java [您可以为它创建use jdeps tool],并使用Java 9下的项目中相应的编译类[使用jar工具]更新jar。
  • (您拥有依赖项)将jar永久迁移到Java 9本身,在Java 9中,它将在编译和打包后由module-info.class本身组成。
mnowg1ta

mnowg1ta2#

您可以使用ModiTect Maven plug-in将模块描述符添加到JAR中,并使用该模块创建模块化运行时映像。
免责声明:我是ModiTect的作者。

hmae6n7t

hmae6n7t3#

让我试着解释一下这方面的技术背景:
问题中给出的版本2.9.9中的joda-time是一个非模块化jar,它不包含module-info.class,也不使用Automatic-Module-Name将自身声明为自动模块:在其META-INF/MANIFEST.MF中
真实的模块中的类不能调用类路径上的类,因此您不能在该版本的module-info中使用“requires jode.time”。
自动模块可以使用ClassPath上的类。要在真实的模块中使用非模块化jar中的类,可以使用本身就是自动模块的 Package 。
到目前为止,已经存在joda-time的2.10.1版本,它是一个自动模块,并声明“Automatic-Module-Name:org.joda.time”,这样您就可以在新版本真实的模块中使用“requiresorg.joda.time”。
现在,新的jlink工具不能直接操作非模块化jar或自动jar,maven-jlink插件目前基本上只是一个围绕jlink工具的maven Package 器,将其配置参数转换为jlink工具的参数。
为了为使用混合Maven依赖项和真实的模块、自动模块和非模块化jar的项目创建自定义Java运行时,您必须了解真实模块、自动模块和非模块化jar的所有系统模块依赖项,然后使用--add-modules参数与这些依赖项jlink。
要收集系统模块依赖关系,您可以使用新的jdeps工具,并使用--print-module-deps或--list-deps参数,具体取决于所使用的实际JDK版本。
如果您在项目中使用Maven,您可以通过创建或使用一个Maven插件来自动执行该任务。

rn0zuynd

rn0zuynd4#

我在我的一个项目中也遇到过类似的问题。首先,我尝试了moditect-maven-plugin,效果很好!但是,使用这个插件,你必须分别配置每个缺少模块描述符的依赖项。如果你有很多缺少模块描述符的依赖项,这会变得很麻烦。
因此,我决定开发一个新的maven插件jigsaw-maven-plugin(参见https://github.com/ghackenberg/jigsaw-maven-plugin)。该插件提供了三个目标,用于修补 * 所有 * 未命名模块(参见步骤3)以及链接和打包这些模块(参见步骤4和5)

  • 在打补丁、链接和打包之前,* 您需要在中构建项目JAR(参见步骤1),并将项目依赖关系(参见步骤2)复制到一个公共位置(例如${project.build.directory}/modules)。也许您可以使用以下构建插件配置开始(参见GitHub page了解更多详细信息):
    步骤1:生成存档
<plugin>
  <artifactId>maven-jar-plugin</artifactId>
  <version>3.3.0</version>
  <configuration>
    <outputDirectory>${project.build.directory}/modules</outputDirectory>
  </configuration>
</plugin>

步骤2:复制依赖项

<plugin>
  <artifactId>maven-dependency-plugin</artifactId>
  <version>3.4.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:修补 * 所有 * 未命名的模块

modulePath中搜索缺少模块描述符的JAR,使用jdepsjavac生成缺少的模块描述符,并使用java.util.zip将它们添加到相应的JAR中。

<plugin>
  <groupId>io.github.ghackenberg</groupId>
  <artifactId>jigsaw-maven-plugin</artifactId>
  <version>1.1.3</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.1.3</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.1.3</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>

相关问题