0

i hope you are doing well in this difficult period,

i'm developping a JavaFx client for my rest web services and while running my app there is a weird exception that point my LoginPresenter class, i'hv checked all the source path but nothing to signal, so i came here to ask for some help ,here is the error:

    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$2(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$9(LauncherImpl.java:846)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(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$11(GtkApplication.java:277)
    ... 1 more
Exception running application fr.orleans.univ.projet.App

Here is my code:

the controller 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é!");
        }
    }
}

This is my 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;
    }
}

this is my 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();
    }
}

and finnaly this is my 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>
8
  • 1
    The exception is raised simply because the path to the FXML is wrong. Commented Apr 18, 2020 at 14:41
  • i don't understand why it is wrong, my fxml file is here "src/main/java/ressources/login.fxml" Commented Apr 18, 2020 at 14:46
  • How are you running it? Since it doesn't appear to be in a package folder then you'll need to specify the absolute location. ie "/login.fxml" then you need to make sure your ressources folder is included either with your compiled classes, or is on your classpath. You ide should help you with that. Commented Apr 18, 2020 at 14:49
  • 1
    Is LoginPresenter in a package? getClass().getResourceAsStream("login.fxml") will look for login.fxml in the same package. The important thing is not where everything is in the src layout, but in the actual build. Commented Apr 18, 2020 at 14:49
  • Slightly off-topic: I don't recommend using the load(InputStream) method (unless you're doing something really weird, like loading the FXML from a server, or generating it on the fly). Use load(URL) instead: getClass().getResource("path/to/file.fxml"). This won't solve this problem, but it might avoid others. Commented Apr 18, 2020 at 14:51

1 Answer 1

2

Your LoginPresenter class is (according to the stack trace) in the package fr.orleans.univ.projet.view.

Using LoginPresenter.class.getResourceAsStream("login.fxml") will look for the resource login.fxml in the same package that LoginPresenter is located in. According to your comment, you placed login.fxml in the source folder src/main/java/resources (I assume "ressources" is a typo), which (with standard configuration in most IDEs or build tools) will place it in the default package in the build.

You can fix this either

  1. By providing the absolute path to the FXML file. Since you have this in the default package, this means using

    LoginPresenter.class.getResourceAsStream("/login.fxml")
    

    (note the leading /)

  2. or by placing login.fxml in the same package, which you would do by putting it in the source folder src/main/java/resources/fr/orleans/univ/projet/view.

Generally, I think the latter solution is better.

You also need to ensure the FXML file is deployed during the build; if you're using a build tool such as Maven or Gradle this should happen by default; if you are using a vanilla build from your IDE, you may need to configure it to ensure this happens.

If you need further troubleshooting, you should check the layout of the buid folder (not the source folder). Depending on your build tool or IDE, this can be one of build,bin, target, target/classes, etc. Look in the build folder and check the relationship between LoginPresenter.class and login.fxml.

One slightly off-topic point; I strongly recommend using a resource URL to load the FXML, rather than a stream; i.e. use

LoginPresenter.class.getResource(...)

instead of

LoginPresenter.class.getResourceAsStream(...)

The reason is that the stream version of the load method fails to set the FXMLLoader's location property (because there's no location specified); consequently, for example, location resolution will not work in the FXML file.

Sign up to request clarification or add additional context in comments.

8 Comments

I'm using intellIj, so when i move the login.fxml to the view package, the method getRasourceAsStream() update the location automatically. and still not working when i run, if i use getClass(), this will create another problem because my class is static and use it in my controller to getInstance(this)
Yes, there's no need to use getClass(); I updated that. What do you mean by "the method getResourceAsStream() update the location automatically? What did it update it to?
@Fraxn Also check the build folder, as I describe in the update to the answer.
i just tried getResource("login.fxml") not working too :/, i meant that wherever when i move my login.fxml file the value in getResourcesAstream("path") get updated automatically by intellij
@Fraxn Updated to what? Did you check the build folder and make sure the FXML file is there?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.