使用 Spring Boot 执行时应用程序启动方法中的 JavaFX 异常
JavaFX Exception in Application start method when executed with Spring Boot
我已经创建了一个简单的 javaFX 程序,并且我通过将项目设为 maven 项目来向 javaFX 添加 spring 引导。在添加 spring 引导之前,我没有收到任何错误,应用程序运行良好。
我在下面提供了完整的代码
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<groupId>groupId</groupId>
<artifactId>RMI-DesktopClient</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
AlarmsystemApplication.java
@Configuration
@SpringBootApplication
public class AlarmSystemApplication extends Application {
private ConfigurableApplicationContext applicationContext;
@Override
public void init() throws Exception {
this.applicationContext = SpringApplication.run(AlarmSystemApplication.class);
}
@Override
public void stop() throws Exception {
applicationContext.close();
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
Login.loadView(stage);
}
}
Login.java
public class Login {
public static void loadView(Stage stage) {
try {
Parent view = FXMLLoader.load(Login.class.getResource("../../../../../resources/com.ui.views/Login.fxml"));
stage.setScene(new Scene(view));
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Login.fxml
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.alarmsystem.ui.views.Login">
<children>
<Label layoutX="137.0" layoutY="157.0" text="Hello JavaFX">
<font>
<Font size="59.0" />
</font>
</Label>
</children>
</AnchorPane>
我得到的错误
Exception in Application start method
2020-04-23 22:33:12.134 INFO 7228 --- [lication Thread] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-04-23 22:33:12.136 INFO 7228 --- [lication Thread] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2020-04-23 22:33:12.139 INFO 7228 --- [lication Thread] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
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$launchApplication4(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: Location is required.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3207)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at com.alarmsystem.ui.views.Login.loadView(Login.java:16)
at com.alarmsystem.ui.AlarmSystemApplication.start(AlarmSystemApplication.java:34)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication11(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait4(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null2(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater3(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$null7(WinApplication.java:177)
... 1 more
Exception running application com.alarmsystem.ui.AlarmSystemApplication
Process finished with exit code 1
文件结构
资源路径
我不确定这是否与 Spring 相关;您用于 FXML 的资源名称不是有效的资源名称(并且堆栈跟踪表明无法找到 FXML 文件是问题所在)。
具体来说,资源名称中不能有.
,所以..
和com.ui.views
都是无效的。
所以这里有两个问题:一个是资源名称与其中指定的"parent directories"不兼容,另一个是您创建了一个文件夹(不是 软件包 )在 resources
下,其中包含非法的 .
字符。另请注意,resources
是一个 source 文件夹,在运行时不可用。
因此,首先,在名为 com.ui.views
的资源下创建一个 包 并将 FMXL 放在那里。我不使用 IntelliJ,所以我不确定是否有这样做的选项,但如果没有,您可以创建一个文件夹 com
、一个名为 ui
的子文件夹和一个子文件夹名为 views
的那个,并将 FXML 文件放在 views
.
中
那么 FXML 的正确资源名称,假设您正在为您的构建使用 Maven 默认值,是
Parent view = FXMLLoader.load(Login.class.getResource("/com/ui/views/Login.fxml"));
如果你稍微重组,使 FXML 文件和 Login
class 在同一个包中(即你在 resources
下创建一个 com.alarmsystem.ui.views
包),然后你可以做
Parent view = FXMLLoader.load(Login.class.getResource("Login.fxml"));
如果您需要进一步排除故障,您可以通过查看 target/classes
文件夹来查看资源的部署位置(因此可以在 runtime 中找到它们) .
我已经创建了一个简单的 javaFX 程序,并且我通过将项目设为 maven 项目来向 javaFX 添加 spring 引导。在添加 spring 引导之前,我没有收到任何错误,应用程序运行良好。 我在下面提供了完整的代码
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<groupId>groupId</groupId>
<artifactId>RMI-DesktopClient</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
AlarmsystemApplication.java
@Configuration
@SpringBootApplication
public class AlarmSystemApplication extends Application {
private ConfigurableApplicationContext applicationContext;
@Override
public void init() throws Exception {
this.applicationContext = SpringApplication.run(AlarmSystemApplication.class);
}
@Override
public void stop() throws Exception {
applicationContext.close();
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
Login.loadView(stage);
}
}
Login.java
public class Login {
public static void loadView(Stage stage) {
try {
Parent view = FXMLLoader.load(Login.class.getResource("../../../../../resources/com.ui.views/Login.fxml"));
stage.setScene(new Scene(view));
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Login.fxml
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.alarmsystem.ui.views.Login">
<children>
<Label layoutX="137.0" layoutY="157.0" text="Hello JavaFX">
<font>
<Font size="59.0" />
</font>
</Label>
</children>
</AnchorPane>
我得到的错误
Exception in Application start method
2020-04-23 22:33:12.134 INFO 7228 --- [lication Thread] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-04-23 22:33:12.136 INFO 7228 --- [lication Thread] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2020-04-23 22:33:12.139 INFO 7228 --- [lication Thread] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
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$launchApplication4(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: Location is required.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3207)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at com.alarmsystem.ui.views.Login.loadView(Login.java:16)
at com.alarmsystem.ui.AlarmSystemApplication.start(AlarmSystemApplication.java:34)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication11(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait4(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null2(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater3(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$null7(WinApplication.java:177)
... 1 more
Exception running application com.alarmsystem.ui.AlarmSystemApplication
Process finished with exit code 1
文件结构
资源路径
我不确定这是否与 Spring 相关;您用于 FXML 的资源名称不是有效的资源名称(并且堆栈跟踪表明无法找到 FXML 文件是问题所在)。
具体来说,资源名称中不能有.
,所以..
和com.ui.views
都是无效的。
所以这里有两个问题:一个是资源名称与其中指定的"parent directories"不兼容,另一个是您创建了一个文件夹(不是 软件包 )在 resources
下,其中包含非法的 .
字符。另请注意,resources
是一个 source 文件夹,在运行时不可用。
因此,首先,在名为 com.ui.views
的资源下创建一个 包 并将 FMXL 放在那里。我不使用 IntelliJ,所以我不确定是否有这样做的选项,但如果没有,您可以创建一个文件夹 com
、一个名为 ui
的子文件夹和一个子文件夹名为 views
的那个,并将 FXML 文件放在 views
.
那么 FXML 的正确资源名称,假设您正在为您的构建使用 Maven 默认值,是
Parent view = FXMLLoader.load(Login.class.getResource("/com/ui/views/Login.fxml"));
如果你稍微重组,使 FXML 文件和 Login
class 在同一个包中(即你在 resources
下创建一个 com.alarmsystem.ui.views
包),然后你可以做
Parent view = FXMLLoader.load(Login.class.getResource("Login.fxml"));
如果您需要进一步排除故障,您可以通过查看 target/classes
文件夹来查看资源的部署位置(因此可以在 runtime 中找到它们) .