-1

I'm developping an desktop app in javafx, and unlike Intellij he jar file return null for getClass().getResource(pagePath).

When i build and run the app with Intellij all work fine and do the job, but after i created the artifact and run the .jar file with a command line i got an error :

'Exception in thread "JavaFX Application Thread"

java.lang.NulPointerException: Location is required.' After many researches and tests i found out that the call getClass().getResource(pagepath) return null in the .jar but not with Intellij. I've tried to change the way to write the path, change the patterns and change the project' structure.

Here the incriminated method

protected void loadPage(ActionEvent event, String pagePath) throws IOException {
        System.out.println(getClass().getResource(pagePath));
        Parent pageParent = FXMLLoader.load(getClass().getResource(pagePath));
        Scene newPage = new Scene(pageParent);
        pageParent.getStylesheets().add(Views.CSS);
        Stage window = (Stage) ((javafx.scene.Node)event.getSource()).getScene().getWindow();
        window.setScene(newPage);
        window.show();
    }

The initialisation of the programm work, the .jar file launch the first page correctly with this method, in the main class.

@Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource(Views.XML_ACCUEIL));
        primaryStage.getIcons().add(new Image(Views.APP_ICON));
        primaryStage.setTitle(Views.APP_NAME);
        primaryStage.setScene(new Scene(root, Views.WIDTH, Views.HEIGHT));
        primaryStage.show();
    }

The View class look like this:

public class Views {
    public static final String home = System.getProperty("user.home");
    public static final String REGISTER_FOLDER = home + File.separator + "Desktop" + File.separator;
    public static final String XML_ACCUEIL = "resources/accueil.fxml";
    public static final String XML_VENTE_FORM = "resources/vente_form.fxml";
    public static final String XML_DEPOT_FORM = "resources/depot_form.fxml";
    public static final String XML_TECHNIQUE_FORM_1 = "resources/technique_form_1.fxml";
    public static final String XML_TECHNIQUE_FORM_2 = "resources/technique_form_2.fxml";
    public static final String XML_TECHNIQUE_FORM_3 = "resources/technique_form_3.fxml";
    //{some others var}
    public static final String CSS = "sample/resources/style.css";
    public static final String APP_NAME = "World Of Cars Desktop";
    public static final String APP_ICON = "sample/resources/logo_petit.png";
    public static final int WIDTH = 1280;
    public static final int HEIGHT = 720;
}

Here's the structure:

-src
    -sample
        -controller
            {all my controller class}
        -resources
            {all my fxml files}
        -DocFiller
        -Main
        -Views

With Intellij all work perfectly like i said, but the .jar file just launch the home page and when i use a button, normally the loadPage method is called and the next page appear but instead of that, the error is throw when i try to lad any other page than the home page. All the pages, images and ressources are store and called with the same way.

  • How did you create the jar? IDE tool, maven, gradel, ...? – Tobias Jul 02 '19 at 12:13
  • With the IDE tool – Julien Madrias Jul 02 '19 at 12:21
  • When using e.g. maven there could be the problem, that the fxml files are just not recognized as resources. It's a bit unlikely that the IDE tool has the same problems, but to be shure you could check the jar file if it even includes the fxml files (by opening it with 7zip or a similar program). – Tobias Jul 02 '19 at 12:32
  • I already checked, it's one of the first things i did but they are include. And the main class see them, I can change the home page by any other page, the problem is just for the controllers. – Julien Madrias Jul 02 '19 at 12:44

2 Answers2

1

I would have expected "/accueil.fxml" or "/resources/accueil.fxml". Look in the jar with 7tzip or such what the real path is.

The resource path "resources/accueil.fxml" indicates that in the class path, under the subdirectory of getClass() (the class' package directory) there should be a subdirectory resources.

An other error would be that the file names are only case-insensitive in Windows, when not starting a jar. A jar (zip) file, Linux and Mac all have case-sensitive file names. Check the case-sensitive spelling.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • My bad, i didn't specify the structure, the resources subdirectory exist. I'm editing my post to add it. And I already check for the path spelling and the intern path of the jar is right. – Julien Madrias Jul 02 '19 at 12:07
  • The class and fxml are in the jar as `/sample/Main.class` and `/sample/resources/accueil.fxml`? for a controller class an absolute path is needed `/sample/resources/accueil.fxml` – Joop Eggen Jul 02 '19 at 12:28
  • I tried with getAbsolutePath() to be sure i did'nt make a misatke ine the path but with this even Intellij return null with `getClass().getResource(pagePath)`. And yes the class and fxml are in the jar as `sample/Main.class` and `sample/resources/accueil.fxml` – Julien Madrias Jul 02 '19 at 12:54
  • No, getAbsolutePath (File?) will not do. It can only be some small oversight. The jar contains `/sample/resources/accueil.fxml`? Then both `Main.class.getResource("/sample/resources/accueil.fxml)` (absolute) and `Main.class.getResource("resources/accueil.fxml)` (relative) should not return null. The cause for the troubles is that the IDE has its own class path. – Joop Eggen Jul 02 '19 at 13:01
  • 1
    Thanks to you i found the solution. I was writing the path like `sample/resources/accueil.fxml` instead of `/sample/resources/accueil.fxml` – Julien Madrias Jul 02 '19 at 13:27
-1

SHORT answer: its missign reource folder after compile the project, by default it put all your class and fxml in same folder which cause the issue, you need resource folder seprate same as src strcture.

LONG answer: Manually add resources folder and add src/main/reource from the project as given below imgage, this will copy all resource to requires destination.

at last use below code to fetch correct file to JAVAFX

FXMLLoader.load(SplashController.class.getResource("DashFX.fxml"))

enter image description here

Jubin Patel
  • 1,959
  • 19
  • 38
  • NOTE: answer may very depends on your ide & jdk version * jdk provider & javaFx/openFx version. – Jubin Patel Mar 23 '23 at 04:32
  • Above given answer is for OenJDK 11, intellij 2022/2021, openFX 17. – Jubin Patel Mar 23 '23 at 04:33
  • please don't post the exact same answer to several questions – kleopatra Mar 23 '23 at 05:31
  • @kleopatra when you have multiple open questions from long time, better to given solution at every single place where user can land in future, looks like you only criticize others code, never write your own. – Jubin Patel Mar 24 '23 at 09:25
  • well .. no: duplicates are considered noise - and might be deleted (as was your exact same answer https://stackoverflow.com/a/75819252/203657), please read the moderator's comment under it :) And refrain from trying to attack other users (even though this obviously incorrect one leaves me more amused than annoyed ;) – kleopatra Mar 24 '23 at 11:02