JavaFX 11项目IntelliJ打包JAR后在Ubuntu 20.04及Windows运行报错
问题根因定位
你遇到的是JavaFX项目打包为胖Jar后资源/类加载失败的典型问题,IDEA内运行正常是因为开发环境的类路径和资源路径和Jar包内的运行环境不一致,按以下步骤排查即可解决:
排查&解决步骤
第一步:确认资源文件打包路径正确
用解压工具直接打开生成的Jar包,检查是否存在以下路径的文件:/app/ui/index.fxml/app/data/NUIMLogoIcon.png/app/ui/Controller.class
若缺少对应文件,是IDEA默认不会将src/main/java目录下的非.java文件作为资源打包导致,两种修复方案:
- 将
ui、data等资源目录移动到专门的resources目录下,在IDEA项目结构中将该目录标记为「资源根(Resources Root)」,加载资源时改用类路径绝对路径:getClass().getResource("/ui/index.fxml") - 若不想调整目录结构,在IDEA的Artifact配置中,手动将对应的fxml、png文件添加到Jar输出的
/app/ui、/app/data路径下
第二步:修复FXML类加载器匹配问题
打包为Jar后,FXMLLoader默认使用的类加载器可能无法识别Jar包内的类,修改Main.java中加载FXML的代码,强制指定类加载器:@Override public void start(Stage primaryStage) throws Exception { FXMLLoader fxmlLoader = new FXMLLoader(); fxmlLoader.setLocation(getClass().getResource("ui/index.fxml")); // 强制使用当前类的类加载器加载FXML和控制器 fxmlLoader.setClassLoader(getClass().getClassLoader()); Parent root = fxmlLoader.load(); primaryStage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResourceAsStream("data/NUIMLogoIcon.png")))); primaryStage.setScene(new Scene(root, 740, 600)); primaryStage.show(); }第三步:补全JavaFX模块参数(可选)
若上述步骤完成后仍报错,运行Jar时添加JavaFX模块启动参数即可:java --add-modules javafx.controls,javafx.fxml,javafx.graphics -jar MULECodeLab.jar补充:若仍无法定位问题
你当前贴出的异常栈没有打印最底层的根因,在加载FXML的代码外层添加try-catch打印完整异常栈,可直接定位具体问题:try { // 原有加载FXML的代码 } catch (Exception e) { e.printStackTrace(); // 递归打印所有嵌套异常 Throwable cause = e.getCause(); while (cause != null) { cause.printStackTrace(); cause = cause.getCause(); } }
内容的提问来源于stack exchange,提问作者Syed
相关产品推荐
相关产品推荐

