如何为JavaFX胖Jar获取正确JDK模块并生成自定义运行时
问题
我开发了一个JavaFX应用并制作了胖Jar,该Jar在控制台可正常运行,但存在警告:
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @4efb10bd'
我希望生成包含该胖Jar所需JDK模块的自定义运行时,于是尝试用jdeps --print-module-deps mouseMove-1.0.jar命令获取所需模块,但未得到预期的java.base、java.desktop等JDK模块,反而出现大量未找到类及JDK已移除内部API的提示。
我的需求是获取完整的所需JDK模块列表,用于jlink生成自定义运行时,之后通过$MY_CUSTOM_JVM/bin/java -jar mouseMove-1.0.jar运行应用。具体问题如下:
- 应使用什么jdeps命令来获取正确的jlink所需模块?
- 如何在jlink中处理jdeps显示的JDK已移除内部API模块?
补充疑问:能否将标准Maven程序与模块结合,从自定义类及Maven依赖中提取所用JDK模块以构建自定义JVM镜像?
解决方案
1. 正确的jdeps命令
胖Jar包含了所有依赖(包括JavaFX类),基础jdeps命令无法正确识别模块依赖,需添加参数让工具能解析内部类和模块路径:
jdeps --module-path /path/to/javafx-sdk/lib --add-modules javafx.controls,javafx.fxml --print-module-deps -recursive mouseMove-1.0.jar
--module-path:指定JavaFX SDK的lib目录,让jdeps能找到JavaFX的模块定义--add-modules:明确指定应用用到的JavaFX模块(根据实际情况调整,比如仅用javafx.controls就只写该模块)-recursive:递归分析所有依赖模块,避免遗漏- 若胖Jar包含其他非模块化依赖,可追加
--class-path mouseMove-1.0.jar确保jdeps扫描到所有类
如果你的项目本身是模块化项目(已配置module-info.java),可使用更精准的命令:
jdeps --module-path /path/to/javafx-sdk/lib:mouseMove-1.0.jar --print-module-deps mouseMove-1.0.jar
2. 处理JDK已移除的内部API提示
这类提示源于代码或依赖库使用了JDK未公开的内部API(如sun.*、com.sun.*包下的类),处理方式如下:
- 优先替换API:检查代码或依赖库,将内部API替换为公开JDK API或第三方替代方案。例如用
java.awt.Desktop替代sun.awt.shell.ShellFolder这类内部类。 - 临时兼容(不推荐):若暂时无法替换,可在jdeps命令中添加
--ignore-missing-deps忽略未找到的类,同时手动将必须的模块(如java.desktop)添加到jlink的模块列表中。但该方式可能导致运行时不稳定,因为内部API可能在后续JDK版本中彻底移除。 - 升级依赖版本:若为依赖库使用内部API,尝试升级到支持模块化的最新版本,多数库在JDK 9+已移除对内部API的依赖。
3. Maven与模块化结合构建自定义JVM镜像
可以通过Maven插件实现自动分析依赖并生成镜像,步骤如下:
- 配置maven-jlink-plugin:在pom.xml中添加插件,示例配置:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jlink-plugin</artifactId> <version>3.3.0</version> <extensions>true</extensions> <configuration> <modulePath> <path>${project.build.directory}/modules</path> <path>/path/to/javafx-sdk/lib</path> </modulePath> <addModules> <module>your.module.name</module> <module>javafx.controls</module> </addModules> <outputDirectory>${project.build.directory}/custom-jvm</outputDirectory> </configuration> </plugin>
- 模块化项目配置:确保项目有正确的
module-info.java,Maven依赖的库为模块化(或通过--add-modules处理自动模块)。 - 执行构建:运行
mvn jlink:jlink,插件会自动收集所有所需JDK模块并生成自定义JVM镜像,之后直接用镜像中的java命令运行Jar即可。
内容的提问来源于stack exchange,提问作者adragomir
相关产品推荐
相关产品推荐

