Maven JavaFX项目生成可执行Jar后运行报错求助
问题分析
你遇到的两个打包报错本质上是Java版本不匹配、Eclipse导出方式不兼容JavaFX模块系统、FXML资源路径打包后无法访问这三个问题导致的。
一、先修正基础配置问题(pom.xml)
你的pom.xml里编译目标是Java 8,但依赖的JavaFX 19要求Java 11及以上版本,版本不兼容直接导致运行时组件缺失。同时,javafx-maven-plugin的配置也需要完善。
修改后的pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>TestNEW</groupId> <artifactId>TestNEW</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <!-- 匹配JavaFX 19的Java版本,推荐用17或19 --> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <javafx.version>19</javafx.version> </properties> <build> <!-- 确保资源文件(如FXML)被正确打包 --> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.fxml</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <!-- 主类要写全限定名,你的Main在main包下的话应该是main.Main --> <mainClass>main.Main</mainClass> </configuration> <!-- 添加打包目标 --> <executions> <execution> <id>default-cli</id> <configuration> <launcher>app</launcher> <jlinkImageName>target/app</jlinkImageName> <jlinkZipName>app</jlinkZipName> </configuration> </execution> </executions> </plugin> <!-- 可选:生成包含所有依赖的可执行Jar --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.4.2</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>main.Main</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>${javafx.version}</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>${javafx.version}</version> </dependency> </dependencies> </project>
关键修改点:
- 把Java编译版本改成17(JavaFX 19支持的最低版本是11,17是LTS版本更稳定)
- 配置资源打包规则,确保FXML文件被正确包含到Jar中
- 修正主类的全限定名(你的Main类在
main包下,所以应该是main.Main,之前的配置缺少包名)
二、修正FXML资源加载路径
你的loadScene方法中,Main.class.getClassLoader().getResource(fxmlPath)会从类路径根目录查找资源。请确保Application.fxml文件放在src/main/resources目录下(Maven默认资源目录),这样打包后会被放到Jar的根目录,路径就能正确找到。
另外,可以把加载方式改成更可靠的Main.class.getResource(fxmlPath),它会从当前类所在的包路径查找。修改后的loadScene方法:
private static Scene loadScene(String fxmlPath, Object controller) throws IOException { URL fxmlUrl = Main.class.getResource(fxmlPath); System.out.println(fxmlUrl); // 打印确认路径是否正确 if (fxmlUrl == null) { throw new IOException("FXML文件未找到:" + fxmlPath); } FXMLLoader loader = new FXMLLoader(fxmlUrl); loader.setController(controller); Parent parent = loader.load(); return new Scene(parent); }
调用时如果FXML和Main类同包(放在src/main/resources/main下),就传"/main/Application.fxml";如果在资源根目录,传"/Application.fxml"。
三、正确的打包方式(放弃Eclipse导出,用Maven命令)
Eclipse的「可运行Jar文件」导出方式无法正确处理JavaFX的模块依赖,这是你第一个报错的核心原因。直接用Maven命令打包:
方式1:生成可运行Fat Jar(包含所有依赖)
在项目根目录执行:
mvn clean package assembly:single
打包完成后,在target目录下会生成TestNEW-0.0.1-SNAPSHOT-jar-with-dependencies.jar,运行命令:
java -jar TestNEW-0.0.1-SNAPSHOT-jar-with-dependencies.jar
方式2:生成独立运行镜像(推荐,无Java环境也能运行)
用javafx-maven-plugin的jlink功能,生成包含Java运行时的独立镜像:
mvn clean javafx:jlink
完成后在target/app目录下,找到对应系统的启动脚本(Windows是app.exe,Linux/macOS是app)直接运行即可。
四、报错细节解释
- duplicate entry: module-info.class:JavaFX的每个模块都有自己的
module-info.class,Eclipse提取库到Jar时会重复打包这些文件,用Maven插件打包会自动处理模块冲突。 - JavaFX runtime components are missing:Java 8环境不支持JavaFX 19,且Eclipse导出没有包含JavaFX的模块路径,修正Java版本和用Maven打包后即可解决。
- Location is not set:FXML文件没有被正确打包到Jar中,或者路径写错,修正资源目录和加载方式后即可解决。
内容的提问来源于stack exchange,提问作者Tavernkeeper

