使用mvn javafx:jlink打包JavaFX应用遇自动模块错误
问题描述
尝试用jlink打包JavaFX应用,执行mvn javafx:jlink或mvn clean javafx:jlink时触发以下错误:
Error: automatic module cannot be used with jlink: com.github.oshi from file:///home/me/.m2/repository/com/github/oshi/oshi-core/6.6.2/oshi-core-6.6.2.jar
已知问题根源是oshi-core依赖没有module-info.java,已在pom.xml中添加Moditect插件,但报错依旧。当前Moditect配置如下:
<plugin> <groupId>org.moditect</groupId> <artifactId>moditect-maven-plugin</artifactId> <version>1.0.0.Final</version> <executions> <execution> <id>generate-module-info</id> <phase>generate-sources</phase> <goals> <goal>generate-module-info</goal> </goals> <configuration> <modules> <module> <artifact> <groupId>com.github.oshi</groupId> <artifactId>oshi-core</artifactId> <version>${oshi.version}</version> </artifact> </module> </modules> <jdepsExtraArgs> <arg>--upgrade-module-path=...</arg> <arg>--multi-release=21</arg> </jdepsExtraArgs> </configuration> </execution> </executions> </plugin>
另外不清楚--multi-release=21参数的作用,但不加会出现其他错误。
解决方案
1. 调整Moditect插件的执行逻辑
当前配置仅生成module-info,但未将其嵌入原始jar包,且执行阶段不对,导致jlink仍引用未处理的自动模块jar。修改配置如下:
<plugin> <groupId>org.moditect</groupId> <artifactId>moditect-maven-plugin</artifactId> <version>1.0.0.Final</version> <executions> <!-- 生成module-info文件 --> <execution> <id>generate-module-info</id> <phase>compile</phase> <goals> <goal>generate-module-info</goal> </goals> <configuration> <modules> <module> <artifact> <groupId>com.github.oshi</groupId> <artifactId>oshi-core</artifactId> <version>${oshi.version}</version> </artifact> <!-- 手动指定模块名,避免自动推导异常 --> <moduleName>com.github.oshi</moduleName> </module> </modules> <jdepsExtraArgs> <arg>--multi-release=21</arg> <!-- 移除无效的--upgrade-module-path占位符,如需指定请填写实际路径 --> </jdepsExtraArgs> </configuration> </execution> <!-- 将生成的module-info嵌入到原始jar包 --> <execution> <id>add-module-info-to-artifact</id> <phase>process-classes</phase> <goals> <goal>add-module-info-to-artifact</goal> </goals> <configuration> <modules> <module> <artifact> <groupId>com.github.oshi</groupId> <artifactId>oshi-core</artifactId> <version>${oshi.version}</version> </artifact> <moduleInfo> <file>${project.build.directory}/generated-sources/moditect/com.github.oshi/module-info.java</file> </moduleInfo> </module> </modules> </configuration> </execution> </executions> </plugin>
2. 验证与执行
先执行mvn clean process-classes确认Moditect已正确生成并嵌入module-info,再运行mvn javafx:jlink打包。
关于--multi-release=21的作用
这个参数用于告诉jdeps(Java依赖分析工具):针对Java 21版本分析多版本JAR的依赖。多版本JAR包含不同Java版本的适配类,指定该参数能让jdeps使用对应版本的类生成准确的module-info,避免因版本差异导致的依赖分析错误。你之前不加它报错,说明oshi-core是多版本JAR,必须指定对应Java版本才能正确生成模块信息。
额外检查点
- 确保项目本身是模块化的(拥有自己的
module-info.java),jlink要求所有依赖必须是显式模块。 - 确认本地仓库中oshi-core的jar已被Moditect修改(可解压查看是否包含
module-info.class)。
内容的提问来源于stack exchange,提问作者Lumelore

