含JavaFX依赖的Jar运行异常求助:双击无响应/命令行报空指针
问题描述
我需要创建包含依赖的Jar包,以便脱离源码文件进行传输。但双击该Jar包无任何反应,使用java -jar file.jar命令行运行时出现如下异常:
Exception in thread "main" java.lang.ExceptionInInitializerError at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) Caused by: java.lang.NullPointerException at uip.gui.JavaFxRun.<clinit>(JavaFxRun.java:16) ... 8 more
插件配置
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> <configuration> <classifier>spring-boot</classifier> <mainClass> uip.gui.JavaFxRun </mainClass> </configuration> </execution> </executions> </plugin> </plugins> </build>
JavaFX相关代码
JavaFXClassFrame.java
public class JavaFXClassFrame extends Application { static Logger LOGGER; static { try (FileInputStream ins = new FileInputStream("src/main/resources/log.config")) { LogManager.getLogManager().readConfiguration(ins); LOGGER = Logger.getLogger(JavaFXClassFrame.class.getName()); } catch (IOException e) { LOGGER.log(Level.WARNING, "Error ", e); } } public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { try { FXMLLoader loader = new FXMLLoader(); URL xmlUrl = getClass().getResource("/fileFxml.fxml"); loader.setLocation(xmlUrl); Parent root = loader.load(); stage.setScene(new Scene(root)); stage.show(); LOGGER.log(Level.INFO, "Success "); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error", e); } } }
JavaFxRun.java
public class JavaFxRun { static Logger LOGGER; static { try (FileInputStream ins = new FileInputStream("src/main/resources/log.config")) { LogManager.getLogManager().readConfiguration(ins); LOGGER = Logger.getLogger(JavaFxRun.class.getName()); } catch (Exception e) { LOGGER.log(Level.WARNING, "Error ", e); } } public static void main(String[] args) { JavaFXClassFrame.main(args); } }
问题分析与解决方案
核心问题
- 日志配置读取路径错误:打包成Jar后,
src/main/resources是源码目录路径,在Jar包内部不存在,用FileInputStream无法读取Jar内的资源文件。 - 静态代码块空指针:当读取日志配置失败时,
LOGGER还未初始化就调用LOGGER.log(),直接触发空指针异常。 - Spring Boot与JavaFX打包兼容性:Spring Boot默认打包逻辑对JavaFX支持有限,可能导致JavaFX运行时依赖缺失或主类加载异常。
具体修复步骤
1. 修复日志配置读取方式
改用类加载器的getResourceAsStream读取Jar内部资源,同时确保LOGGER始终被初始化:
修改JavaFxRun的静态代码块:
static { try (InputStream ins = JavaFxRun.class.getClassLoader().getResourceAsStream("log.config")) { if (ins != null) { LogManager.getLogManager().readConfiguration(ins); } LOGGER = Logger.getLogger(JavaFxRun.class.getName()); } catch (Exception e) { System.err.println("加载日志配置失败: " + e.getMessage()); e.printStackTrace(); LOGGER = Logger.getLogger(JavaFxRun.class.getName()); } }
同步修改JavaFXClassFrame的静态代码块:
static { try (InputStream ins = JavaFXClassFrame.class.getClassLoader().getResourceAsStream("log.config")) { if (ins != null) { LogManager.getLogManager().readConfiguration(ins); } LOGGER = Logger.getLogger(JavaFXClassFrame.class.getName()); } catch (IOException e) { System.err.println("加载日志配置失败: " + e.getMessage()); e.printStackTrace(); LOGGER = Logger.getLogger(JavaFXClassFrame.class.getName()); } }
2. 调整打包插件配置(可选)
添加JavaFX专用打包插件,确保JavaFX运行时依赖被正确打包,同时保留Spring Boot插件配置:
<build> <plugins> <!-- JavaFX打包插件 --> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <executions> <execution> <id>default-cli</id> <configuration> <mainClass>uip.gui.JavaFxRun</mainClass> </configuration> </execution> </executions> </plugin> <!-- Spring Boot打包插件 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> <configuration> <classifier>spring-boot</classifier> <mainClass>uip.gui.JavaFxRun</mainClass> </configuration> </execution> </executions> </plugin> </plugins> </build>
3. 测试运行
执行mvn clean package重新打包,用java -jar target/xxx-spring-boot.jar运行Jar包验证。若双击仍无反应,确保系统默认Java版本为OpenJDK 11+且包含JavaFX运行时。
内容的提问来源于stack exchange,提问作者ZabbixJs
相关产品推荐
相关产品推荐

