无VM参数时,如何在Eclipse中部署运行JavaFX可执行JAR
问题详情
我开发了一个JavaFX Windows应用,在安装了e(fx)clipse插件的Eclipse中运行正常,项目执行环境为JavaSE-1.8 (jre1.8.0_161)。将其导出为可执行JAR文件后,在其他Windows电脑上运行时抛出Exception in Application start method异常。网上资料说需要从项目运行配置中复制VM参数,但我的VM参数文本框完全为空。
运行JAR的命令及报错输出:
java -jar my_exported_jar.jar
Exception in Application start method java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389) at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767) Caused by: java.lang.RuntimeException: Exception in Application start method at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.IllegalStateException: Location is not set. at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2434) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409) at com.st.myst25app.MainApp.initStage(MainApp.java:52) at com.st.myst25app.MainApp.start(MainApp.java:36) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863) at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326) at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) ... 1 more Exception running application com.st.myst25app.MainApp
解决方案
问题根源
从报错栈可以看到,最底层的异常是java.lang.IllegalStateException: Location is not set.(非法状态异常:未设置位置),出现在FXMLLoader.load()调用时。这说明程序无法找到FXML文件的正确路径——Eclipse运行时,FXML文件在项目目录下可用相对路径访问,但导出成JAR后,文件被打包进JAR内部,原路径写法失效。
修复步骤
修正FXML加载方式
必须使用类加载器从JAR内部读取FXML资源,替换原来的文件路径写法。例如:
错误写法(依赖本地文件系统路径):FXMLLoader loader = new FXMLLoader(); loader.setLocation(new File("src/com/st/myst25app/MainView.fxml").toURI().toURL());正确写法(从JAR资源中读取):
FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/st/myst25app/MainView.fxml"));注意路径开头的
/表示从JAR根目录开始查找,要与FXML文件在JAR中的实际包路径完全匹配。确保FXML文件被打包进JAR
Eclipse导出JAR时,需确认资源文件被正确包含:- 选择“导出”→“Runnable JAR File”,点击“Next”
- 在“Library handling”中选择合适的打包方式(如“Extract required libraries into generated JAR”)
- 勾选“Export generated class files and resources”选项,确保FXML等资源被纳入JAR
关于VM参数
你的VM参数为空是正常的。Java 8中JavaFX是JRE的内置组件,无需额外VM参数。网上提到的VM参数要求针对的是Java 11及以上版本(JavaFX从JDK分离,需指定模块路径),与你使用的Java 8无关。重新测试
按上述步骤调整后重新导出JAR,用java -jar my_exported_jar.jar命令运行,确认FXML文件能被正确加载。
内容的提问来源于stack exchange,提问作者benino

