将Java项目转为Maven后JavaFX应用无法启动,求解决
JavaFX转Maven后无法启动问题排查
我将Java项目转为Maven项目后,JavaFX应用无法启动,转Maven前应用可正常运行,推测问题出在MainView类中。以下是相关代码、配置及报错信息:
MainView代码
package view; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; import model.*; import java.util.ArrayList; import java.util.Objects; public class MainView extends Application implements Interface{ @Override public void start(Stage stage) { try { Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getResource("MainView.fxml"))); Scene scene = new Scene(root, 1000, 600); stage.setScene(scene); stage.show(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { launch(args); } }
pom.xml配置
<?xml version="1.0" encoding="UTF-8"?> <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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>groupId</groupId> <artifactId>program</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.release>14</maven.compiler.release> <javafx.version>16</javafx.version> <javafx.maven.plugin.version>0.0.6</javafx.maven.plugin.version> </properties> <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> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <release>${maven.compiler.release}</release> </configuration> </plugin> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>${javafx.maven.plugin.version}</version> <configuration> <mainClass>view.MainView</mainClass> </configuration> </plugin> </plugins> </build> </project>
报错堆栈
java.lang.NullPointerException at java.base/java.util.Objects.requireNonNull(Objects.java:208) at view.MainView.start(MainView.java:18) at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456) at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184) at java.base/java.lang.Thread.run(Thread.java:833)
解决方法
报错核心是getClass().getResource("MainView.fxml")返回null,触发了Objects.requireNonNull的空指针异常。原因是Maven默认只编译src/main/java下的.java文件,不会将该目录下的.fxml等非Java文件复制到编译后的target/classes目录,导致运行时找不到fxml文件。
方式一:调整文件结构
将MainView.fxml移动到src/main/resources/view目录下(和MainView类的包路径view对应),Maven会自动将该目录下的资源文件打包到classpath中。
方式二:修改pom.xml配置
在<build>节点中添加资源配置,让Maven同时复制src/main/java下的.fxml文件到classes目录:
<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.fxml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources> <!-- 保留原有的plugins配置 --> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <release>${maven.compiler.release}</release> </configuration> </plugin> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>${javafx.maven.plugin.version}</version> <configuration> <mainClass>view.MainView</mainClass> </configuration> </plugin> </plugins> </build>
额外优化
可以将getResource调用改为从类加载器根目录查找,稳定性更强:
Parent root = FXMLLoader.load(Objects.requireNonNull(MainView.class.getClassLoader().getResource("view/MainView.fxml")));
内容的提问来源于stack exchange,提问作者larppiiis
相关产品推荐
相关产品推荐

