NullPointerException loading fxml file from javafx

2019-09-06 04:32发布

问题:

I'm trying to create javafx applet, using IntelliJ Idea. After building I get three files: .jar, .jnlp and .html. If I launch jar all works fine, but if I try to run app using jnlp or html it throws exception:

java.lang.NullPointerException: Location is required.
    at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
    at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
    at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
    at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
    at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
    at javafx.fxml.FXMLLoader.load(Unknown Source)
    at sample.Main.start(Main.java:14)
    at com.sun.javafx.applet.FXApplet2$2.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$170(Unknown Source)
    at com.sun.javafx.application.PlatformImpl$$Lambda$45/31918841.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(Unknown Source)
    at com.sun.javafx.application.PlatformImpl$$Lambda$44/13936151.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$145(Unknown Source)
    at com.sun.glass.ui.win.WinApplication$$Lambda$34/10055096.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.NullPointerException: Location is required.
    at com.sun.javafx.applet.FXApplet2$2.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$170(Unknown Source)
    at com.sun.javafx.application.PlatformImpl$$Lambda$45/31918841.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(Unknown Source)
    at com.sun.javafx.application.PlatformImpl$$Lambda$44/13936151.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$145(Unknown Source)
    at com.sun.glass.ui.win.WinApplication$$Lambda$34/10055096.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException: Location is required.
    at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
    at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
    at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
    at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
    at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
    at javafx.fxml.FXMLLoader.load(Unknown Source)
    at sample.Main.start(Main.java:14)
    ... 11 more

Why is it so? Jar exactly contains needed fxml located at the specified path.

Java:

package sample;

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

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("/sample/sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }

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

FXML:

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

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Button layoutX="173.0" layoutY="188.0" prefHeight="25.0" prefWidth="255.0" text="Button" />
   </children>
</AnchorPane>

What am I doing wrong? Help please.

回答1:

The problem is in this line:

Parent root = FXMLLoader.load(getClass().getResource("/sample/sample.fxml"));

It is pretty clear that the load method is actually being called with a null argument. And that happens because getResource("/sample/sample.fxml") cannot file that resource.

The resource is missing (or has the wrong path) on the runtime classpath.



回答2:

This is a problem of security. The FXML file is considered as to be loaded from the filesystem of the client, but the "user.dir, read" permission is not tolerated by the Java security manager.

However, it is a problem of signing JavaFX applets. Once signed, the loading works well. Example here: http://web.univ-pau.fr/~barbier/PauWare/My_device/dist/My_device_JavaFX.html

BTW, there is no problem with JavaFX applications (eg, http://www.franckbarbier.com/PauWare/Programmable_thermostat/) that have self-contained widgets in the code (no load of FXML file). Cheers!!