You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maven JavaFX项目生成可执行Jar后运行报错求助

JavaFX项目Maven打包后无法运行的解决方案

问题分析

你遇到的两个打包报错本质上是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)直接运行即可。


四、报错细节解释

  1. duplicate entry: module-info.class:JavaFX的每个模块都有自己的module-info.class,Eclipse提取库到Jar时会重复打包这些文件,用Maven插件打包会自动处理模块冲突。
  2. JavaFX runtime components are missing:Java 8环境不支持JavaFX 19,且Eclipse导出没有包含JavaFX的模块路径,修正Java版本和用Maven打包后即可解决。
  3. Location is not set:FXML文件没有被正确打包到Jar中,或者路径写错,修正资源目录和加载方式后即可解决。

内容的提问来源于stack exchange,提问作者Tavernkeeper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 08:36:14