JavaFx 奇怪的异常!应用程序启动方法中的异常
JavaFx Weird Exception !! Exception in Application start method
我希望你在这个困难时期过得很好,
我正在为我的其余 Web 服务开发一个 JavaFx 客户端,而 运行 我的应用程序有一个奇怪的异常指向我的 LoginPresenter class,我检查了所有源路径但是没有什么信号,所以我来这里寻求帮助,这是错误:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.NullPointerException: inputStream is null.
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2480)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2450)
at fr.orleans.univ.projet/fr.orleans.univ.projet.view.LoginPresenter.getInstance(LoginPresenter.java:39)
at fr.orleans.univ.projet/fr.orleans.univ.projet.PrimaryController.showLogin(PrimaryController.java:22)
at fr.orleans.univ.projet/fr.orleans.univ.projet.App.start(App.java:30)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop(GtkApplication.java:277)
... 1 more
Exception running application fr.orleans.univ.projet.App
这是我的代码:
控制器PrimaryController.class
public class PrimaryController {
private Stage stage;
private Service service;
public PrimaryController(Stage stage, Service service) {
this.stage = stage;
this.service = service;
}
public void showLogin(){
LoginPresenter login = LoginPresenter.getInstance(this);
Scene scene = new Scene(login.getRoot());
stage.setScene(scene);
stage.show();
}
public void tenteLogin(String username, String password) {
service.login(username,password);
if(service.isAuthenticated()){
System.out.println("Connecté!");
}
}
}
这是我的LoginPresenter.class
public class LoginPresenter {
private PrimaryController primaryController;
public void setPrimaryController(PrimaryController primaryController){
this.primaryController=primaryController;
}
@FXML
private TextField username;
@FXML
private PasswordField password;
@FXML
private Parent root;
public Parent getRoot(){
return root;
}
public void login(ActionEvent actionEvent) {
primaryController.tenteLogin(username.getText(),password.getText());
}
public static LoginPresenter getInstance(PrimaryController primaryController){
FXMLLoader loader = new FXMLLoader();
try {
Parent root = loader.load(LoginPresenter.class.getResourceAsStream("login.fxml"));
} catch (IOException e){
e.printStackTrace();
}
LoginPresenter instance = loader.getController();
instance.setPrimaryController(primaryController);
return instance;
}
}
这是我的App.class
public class App extends Application {
// private static Scene scene;
public static void main(String[] args) {
launch();
}
@Override
public void start(Stage stage) {
Service service = new ServiceProxy();
PrimaryController primaryController = new PrimaryController(stage,service);
primaryController.showLogin();
}
}
最后这是我的 login.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<BorderPane fx:id="root" prefHeight="200.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fr.orleans.univ.projet.view.LoginPresenter">
<top>
<Label text="Login" BorderPane.alignment="CENTER">
<font>
<Font size="24.0" />
</font>
</Label>
</top>
<center>
<GridPane BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="94.0" minWidth="10.0" prefWidth="72.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="158.0" minWidth="10.0" prefWidth="128.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label focusTraversable="false" text="Username" />
<Label focusTraversable="false" text="Password" GridPane.rowIndex="1" />
<TextField fx:id="username" GridPane.columnIndex="1" />
<PasswordField fx:id="password" GridPane.columnIndex="1" GridPane.rowIndex="1" />
</children>
</GridPane>
</center>
<bottom>
<Button defaultButton="true" mnemonicParsing="false" onAction="#login" text="Login" BorderPane.alignment="CENTER">
<opaqueInsets>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</opaqueInsets></Button>
</bottom>
</BorderPane>
你的 LoginPresenter
class 在包 fr.orleans.univ.projet.view
.
中(根据堆栈跟踪)
使用 LoginPresenter.class.getResourceAsStream("login.fxml")
将在 LoginPresenter
所在的同一包中查找资源 login.fxml
。根据您的评论,您将 login.fxml
放在源中文件夹 src/main/java/resources
(我假设 "ressources" 是一个拼写错误),它(在大多数 IDE 或构建工具中使用标准配置)将把它放在构建的默认包中。
您可以解决此问题
通过提供 FXML 文件的绝对路径。因为你在默认包中有这个,这意味着使用
LoginPresenter.class.getResourceAsStream("/login.fxml")
(注意前导/
)
- 或者将
login.fxml
放在同一个包中,您可以将其放在源文件夹 src/main/java/resources/fr/orleans/univ/projet/view
中。
总的来说,我认为后一种解决方案更好。
您还需要确保在构建期间部署了 FXML 文件;如果您使用的是 Maven 或 Gradle 等构建工具,则默认情况下会发生这种情况;如果您使用的是 IDE 的原始版本,您可能需要对其进行配置以确保发生这种情况。
如果您需要进一步的故障排除,您应该检查 buid 文件夹(不是源文件夹)的布局。根据您的构建工具或 IDE,这可以是 build
、bin
、target
、target/classes
等之一。查看构建文件夹并检查LoginPresenter.class
和 login.fxml
.
之间的关系
稍微有点跑题的地方;我强烈建议使用资源 URL 来加载 FXML,而不是流;即使用
LoginPresenter.class.getResource(...)
而不是
LoginPresenter.class.getResourceAsStream(...)
原因是stream版本的load方法没有设置FXMLLoader
的location
属性(因为没有指定位置);因此,例如,location resolution 在 FXML 文件中将不起作用。
我希望你在这个困难时期过得很好,
我正在为我的其余 Web 服务开发一个 JavaFx 客户端,而 运行 我的应用程序有一个奇怪的异常指向我的 LoginPresenter class,我检查了所有源路径但是没有什么信号,所以我来这里寻求帮助,这是错误:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.NullPointerException: inputStream is null.
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2480)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2450)
at fr.orleans.univ.projet/fr.orleans.univ.projet.view.LoginPresenter.getInstance(LoginPresenter.java:39)
at fr.orleans.univ.projet/fr.orleans.univ.projet.PrimaryController.showLogin(PrimaryController.java:22)
at fr.orleans.univ.projet/fr.orleans.univ.projet.App.start(App.java:30)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop(GtkApplication.java:277)
... 1 more
Exception running application fr.orleans.univ.projet.App
这是我的代码:
控制器PrimaryController.class
public class PrimaryController {
private Stage stage;
private Service service;
public PrimaryController(Stage stage, Service service) {
this.stage = stage;
this.service = service;
}
public void showLogin(){
LoginPresenter login = LoginPresenter.getInstance(this);
Scene scene = new Scene(login.getRoot());
stage.setScene(scene);
stage.show();
}
public void tenteLogin(String username, String password) {
service.login(username,password);
if(service.isAuthenticated()){
System.out.println("Connecté!");
}
}
}
这是我的LoginPresenter.class
public class LoginPresenter {
private PrimaryController primaryController;
public void setPrimaryController(PrimaryController primaryController){
this.primaryController=primaryController;
}
@FXML
private TextField username;
@FXML
private PasswordField password;
@FXML
private Parent root;
public Parent getRoot(){
return root;
}
public void login(ActionEvent actionEvent) {
primaryController.tenteLogin(username.getText(),password.getText());
}
public static LoginPresenter getInstance(PrimaryController primaryController){
FXMLLoader loader = new FXMLLoader();
try {
Parent root = loader.load(LoginPresenter.class.getResourceAsStream("login.fxml"));
} catch (IOException e){
e.printStackTrace();
}
LoginPresenter instance = loader.getController();
instance.setPrimaryController(primaryController);
return instance;
}
}
这是我的App.class
public class App extends Application {
// private static Scene scene;
public static void main(String[] args) {
launch();
}
@Override
public void start(Stage stage) {
Service service = new ServiceProxy();
PrimaryController primaryController = new PrimaryController(stage,service);
primaryController.showLogin();
}
}
最后这是我的 login.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<BorderPane fx:id="root" prefHeight="200.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fr.orleans.univ.projet.view.LoginPresenter">
<top>
<Label text="Login" BorderPane.alignment="CENTER">
<font>
<Font size="24.0" />
</font>
</Label>
</top>
<center>
<GridPane BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="94.0" minWidth="10.0" prefWidth="72.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="158.0" minWidth="10.0" prefWidth="128.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label focusTraversable="false" text="Username" />
<Label focusTraversable="false" text="Password" GridPane.rowIndex="1" />
<TextField fx:id="username" GridPane.columnIndex="1" />
<PasswordField fx:id="password" GridPane.columnIndex="1" GridPane.rowIndex="1" />
</children>
</GridPane>
</center>
<bottom>
<Button defaultButton="true" mnemonicParsing="false" onAction="#login" text="Login" BorderPane.alignment="CENTER">
<opaqueInsets>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</opaqueInsets></Button>
</bottom>
</BorderPane>
你的 LoginPresenter
class 在包 fr.orleans.univ.projet.view
.
使用 LoginPresenter.class.getResourceAsStream("login.fxml")
将在 LoginPresenter
所在的同一包中查找资源 login.fxml
。根据您的评论,您将 login.fxml
放在源中文件夹 src/main/java/resources
(我假设 "ressources" 是一个拼写错误),它(在大多数 IDE 或构建工具中使用标准配置)将把它放在构建的默认包中。
您可以解决此问题
通过提供 FXML 文件的绝对路径。因为你在默认包中有这个,这意味着使用
LoginPresenter.class.getResourceAsStream("/login.fxml")
(注意前导
/
)- 或者将
login.fxml
放在同一个包中,您可以将其放在源文件夹src/main/java/resources/fr/orleans/univ/projet/view
中。
总的来说,我认为后一种解决方案更好。
您还需要确保在构建期间部署了 FXML 文件;如果您使用的是 Maven 或 Gradle 等构建工具,则默认情况下会发生这种情况;如果您使用的是 IDE 的原始版本,您可能需要对其进行配置以确保发生这种情况。
如果您需要进一步的故障排除,您应该检查 buid 文件夹(不是源文件夹)的布局。根据您的构建工具或 IDE,这可以是 build
、bin
、target
、target/classes
等之一。查看构建文件夹并检查LoginPresenter.class
和 login.fxml
.
稍微有点跑题的地方;我强烈建议使用资源 URL 来加载 FXML,而不是流;即使用
LoginPresenter.class.getResource(...)
而不是
LoginPresenter.class.getResourceAsStream(...)
原因是stream版本的load方法没有设置FXMLLoader
的location
属性(因为没有指定位置);因此,例如,location resolution 在 FXML 文件中将不起作用。