我使用这个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:
我真的很感激你的帮助。谢谢。
4条答案
按热度按时间798qvoo81#
我相信这与插件没有太大关系。模块
joda.time
在你的情况下似乎是一个 * 自动模块 *。jlink
tool does not support linking of automatic modules,因为它们可以依赖于类路径的任意内容,这与自包含Java运行时的理念背道而驰。所以有两种方法来解决这个问题:-
module-info.java
[您可以为它创建usejdeps
tool],并使用Java 9下的项目中相应的编译类[使用jar
工具]更新jar。module-info.class
本身组成。mnowg1ta2#
您可以使用ModiTect Maven plug-in将模块描述符添加到JAR中,并使用该模块创建模块化运行时映像。
免责声明:我是ModiTect的作者。
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插件来自动执行该任务。
rn0zuynd4#
我在我的一个项目中也遇到过类似的问题。首先,我尝试了
moditect-maven-plugin
,效果很好!但是,使用这个插件,你必须分别配置每个缺少模块描述符的依赖项。如果你有很多缺少模块描述符的依赖项,这会变得很麻烦。因此,我决定开发一个新的maven插件
jigsaw-maven-plugin
(参见https://github.com/ghackenberg/jigsaw-maven-plugin)。该插件提供了三个目标,用于修补 * 所有 * 未命名模块(参见步骤3)以及链接和打包这些模块(参见步骤4和5)。${project.build.directory}/modules
)。也许您可以使用以下构建插件配置开始(参见GitHub page了解更多详细信息):步骤1:生成存档
步骤2:复制依赖项
步骤3:修补 * 所有 * 未命名的模块
在
modulePath
中搜索缺少模块描述符的JAR,使用jdeps
和javac
生成缺少的模块描述符,并使用java.util.zip
将它们添加到相应的JAR中。步骤4:链接模块
使用
jlink
链接模块。步骤5:封装模块
使用
jpackage
封装模块。