JavaFx8 (+Maven): error when loading the fxml file

I am trying to write a JavaFx8 application using Maven. I wrote a simple application main class and a fxml file (a root fxml file that does nothing).

When I try to load the fxml root file I have the error "Location is not set":

Exception in Application start method
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:483)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:363)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:303)
    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:483)
    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:875)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(LauncherImpl.java:157)
    at com.sun.javafx.application.LauncherImpl$$Lambda$53/99550389.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Location is not set.
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2428)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2403)
    at org.aklal.todofx.tasks.App.initRootLayout(App.java:58)
    at org.aklal.todofx.tasks.App.start(App.java:31)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
    at com.sun.javafx.application.LauncherImpl$$Lambda$56/1712616138.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
    at com.sun.javafx.application.PlatformImpl$$Lambda$49/1268447657.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
    at com.sun.javafx.application.PlatformImpl$$Lambda$52/511893999.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
    at com.sun.javafx.application.PlatformImpl$$Lambda$50/1851691492.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null$45(GtkApplication.java:126)
    at com.sun.glass.ui.gtk.GtkApplication$$Lambda$42/584634336.run(Unknown Source)
    ... 1 more
Exception running application org.aklal.todofx.tasks.App

I am not new to JavaFx8 and I already had this kind of error but this time I do not find the problem.

My classes are: App.java

package org.aklal.todofx.tasks;

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;


public class App extends Application {

        private Stage primaryStage;
        private BorderPane rootLayout;

        public App() {
                System.out.println("TEST");
        }

        @Override
        public void start(Stage primaryStage) {
                this.primaryStage = primaryStage;
                this.primaryStage.setTitle("TEST App (JavaFx with Maven)");

                initRootLayout();
        }

        public void initRootLayout() {
                try {
                        //to check classpaths 
                        Unused un = new Unused();
                        System.out.println("TESTAPP\n\t" + this.getClass());

                        // Load root layout from fxml file.
                        FXMLLoader loader = new FXMLLoader();
                        loader.setLocation(App.class.getResource("view/RootLayout.fxml"));
                        //loader.setLocation(App.class.getResource("TestRootLayout.fxml"));
                        rootLayout = (BorderPane) loader.load();

                        // Show the scene containing the root layout.
                        Scene scene = new Scene(rootLayout);
                        primaryStage.setScene(scene);
                        primaryStage.show();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }


        public Stage getPrimaryStage() {
                return primaryStage;
        }

        public static void main(String[] args) {
                launch(args);
        }
}

RootLayout.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>


<BorderPane prefHeight="500.0" prefWidth="1024.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
        <!-- TODO Add Nodes -->
</BorderPane>

I checked the classpathes printing out the getClass output (Is that the correct way to have classpath?), to do so I wrote an "Unused.java" class in the fxml file package:

package org.aklal.todofx.tasks.view;

public class Unused {
        public Unused(){
                System.out.println("Unused\n\t" + this.getClass());
        }

}

When I run the App, the getClass ouputs are:

Unused

   class org.aklal.todofx.tasks.view

Unused APP

   class org.aklal.todofx.tasks.App

So in my opinion the path ("view/RootLayout.fxml") I give to loader.setLocation is correct, isn't it?.

I also tried to put the root fxml file (renamed TestRootLayout) in the main class' package, I still have the error.

Can anybody see an error?

Note

I already wrote JavaFx apps but I never used Maven to do it, the purpose of this project is to set a JavaFx8 project with Maven. I think my problem does not come from Maven but I give you the commands I done to set my project, maybe there is something wrong: I did the command:

mvn archetype:generate -DgroupId=org.aklal -DartifactId=javafx-with-maven -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

I modified the pom.xml file:

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.aklal</groupId>
  <artifactId>javafx-with-maven</artifactId>

  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>

  <name>javafx-with-maven</name>

  <url>http://maven.apache.org</url>

    <dependencies>
        <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
        </dependency>
    </dependencies>


    <build>
        <finalName>JavaFXSimpleApp</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>        
            <plugin>
                <groupId>com.zenjava</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>2.0</version>
                <configuration>
                    <mainClass>org.aklal.todofx.tasks.App</mainClass>
                </configuration>
            </plugin>
        </plugins>    
    </build>
</project>

and then:

mvn eclipse:eclipse

and in Eclipse: Import -> Existing Projects into workspace

fxrt.jar is included in JRE System Library

Update:

To check if the problem has not a more general reason, I wrote the main class with hard coded elements:

public class App extends Application {

    public static void main(String args[]) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        Button bouton = new Button("Click");
        bouton.setOnAction(e -> System.out.println("Clicked!"));
        StackPane root = new StackPane();
        root.getChildren().add(bouton);
        stage.setScene(new Scene(root));
        stage.setWidth(300);
        stage.setHeight(300);
        stage.setTitle("JavaFx8 with Maven");
        stage.show();
    }
}

It works, so I guess everything is in order. The question remains: why does the setLocation not work?

Update:

There is definitely a problem with the path to the fxml file. If I change:

FXMLLoader loader = new FXMLLoader();
loader.setLocation(App.class.getResource("view/RootLayout.fxml"));

with:

String pathToFxml = "absolute_path/RootLayout.fxml";
URL fxmlUrl = new File(pathToFxml).toURI().toURL();
loader.setLocation(fxmlUrl);

then it works

Answers


for now the jar I created did not have fxml files. I guess I made a mistake, I will give one more try and let you know

You need to add the FXML file in a sub-directory of src/main/resources not src/main/java

If you call App.class.getResource("view/RootLayout.fxml") then the FXML file has to be in the directory: src/main/resources/mypackage/view where mypackage is the package of the class App.

If you call it with a leading slash: App.class.getResource("/view/RootLayout.fxml") then the FXML file has to be in the directory: src/main/resources/view

Double-check if the FXML-file is at the expected location in the JAR-file.


As Puce said, if you call App.class.getResource("view/RootLayout.fxml") then the FXML file has to be in the directory: src/main/resources/mypackage/view where mypackage is the package of the class App.

So , instead of using App.class

FXMLLoader loader = new FXMLLoader(); 
loader.setLocation(App.class.getResource("view/RootLayout.fxml"));

Try ClassLoader

FXMLLoader loader = new FXMLLoader(); 
loader.setLocation(ClassLoader.getSystemResource("view/RootLayout.fxml"));

Need Your Help

Git commit not working with Emacs and Ubuntu

git ubuntu emacs

I'm running it in vagrant on ubuntu 14.04. It was working fine before but now it's not.

jQuery - on click class - get other classes

javascript jquery html css

Please see my previous question which I've solved with the help of the fine StackOverFlow Community, here: jQuery How to get element id based on what was clicked AND get child element Id