簡體   English   中英

加載 FXML 時出現 NullPointerException

[英]NullPointerException when loading an FXML

我收到關於我的 FXML 位置的 NullPointerException。 然而,這只是在我升級我的 JavaFX 版本后才開始發生(我需要 13 才能滿足項目要求)。

我的主要 class:

public class Main extends Application {

@Override
public void start(Stage primaryStage) throws IOException {

    String path = "/fxml/loginScene.fxml";

    Parent root = FXMLLoader.load(getClass().getResource(path));
    primaryStage.initStyle(StageStyle.UNDECORATED);

    Scene scene = new Scene(root);
    primaryStage.setScene(scene);
    primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("/imgs/icon.png")));
    primaryStage.show();
}

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

模塊信息

module main {
requires javafx.controls;
requires javafx.fxml;
requires jfoenix;
requires vlcj;

opens me.fullcam.mosaicov2 to javafx.fxml;
exports me.fullcam.mosaicov2;
}

我的目錄:

在此處輸入圖像描述

例外:

    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:835)
Caused by: java.lang.NullPointerException: Location is required.
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3230)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)
    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)
    at main/me.fullcam.mosaicov2.Main.start(Main.java:20)

我的 build.gradle

    plugins {
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
    id 'org.beryx.jlink' version '2.12.0'
}

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'uk.co.caprica', name: 'vlcj', version: '4.2.0'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.0.1'
    compile group: 'com.google.http-client', name: 'google-http-client', version: '1.23.0'
    compile group: 'com.jfoenix', name: 'jfoenix', version: '8.0.9'
    compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.28'
}

javafx {
    version = "13"
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

mainClassName = "$moduleName/me.fullcam.mosaicov2.Main"

jlink {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'mosaico-desktop'
    }
}

我認為一切都井井有條,但沒有將資源添加到類路徑中。 我還沒有找到類似的東西。 我正在使用 IntelliJ。

我試過./gradlew clean --info run ,但那是我的堆棧跟蹤:

> Task :run FAILED
Task ':run' is not up-to-date because:
  Task has not declared any outputs despite executing actions.
Starting process 'command '/usr/lib/jvm/java-12-oracle/bin/java''. Working directory: /home/leonardo/Modelos/IdeaProjects/FullCam/Desktop/mosaico-desktop-v2 Command: /usr/lib/jvm/java-12-oracle/bin/java --add-modules javafx.base,javafx.controls,javafx.fxml,javafx.graphics,javafx.media --module-path /home/leonardo/Modelos/IdeaProjects/FullCam/Desktop/mosaico-desktop-v2/build/classes/java/main:/home/leonardo/Modelos/IdeaProjects/FullCam/Desktop/mosaico-desktop-v2/build/resources/main:/root/.gradle/caches/modules-2/files-2.1/uk.co.caprica/vlcj/4.2.0/727b20426956174d64c6817367f45080ad95a4d0/vlcj-4.2.0.jar:/root/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-databind/2.0.1/1d160beb3f8924d5b98d03d94a149021146f71cc/jackson-databind-2.0.1.jar:/root/.gradle/caches/modules-2/files-2.1/com.google.http-client/google-http-client/1.23.0/8e86c84ff3c98eca6423e97780325b299133d858/google-http-client-1.23.0.jar:/root/.gradle/caches/modules-2/files-2.1/com.jfoenix/jfoenix/8.0.9/71da4db8303be22f6366df8933dd93519398c8f8/jfoenix-8.0.9.jar:/root/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-simple/1.7.28/cf5f2cf3c31e0e41b68d932d756398a1238d4456/slf4j-simple-1.7.28.jar:/root/.gradle/caches/modules-2/files-2.1/org.openjfx/javafx-fxml/13/2c1016c361ce5797927e9e14847fbca9bebf3bd5/javafx-fxml-13-linux.jar:/root/.gradle/caches/modules-2/files-2.1/org.openjfx/javafx-controls/13/bcedf8eb6e11c2a7908b3126004d41274f6334f3/javafx-controls-13-linux.jar:/root/.gradle/caches/modules-2/files-2.1/org.openjfx/javafx-controls/13/6cd7169d2a729846c35fba9dc65af23a10ca253b/javafx-controls-13.jar:/root/.gradle/caches/modules-2/files-2.1/org.openjfx/javafx-media/13/d3626ef7290012a1e55a32532977ed78edc02548/javafx-media-13-linux.jar:/root/.gradle/caches/modules-2/files-2.1/org.openjfx/javafx-graphics/13/d853d12684f60037dfeea1a47e61396e0febfdfd/javafx-graphics-13-linux.jar:/root/.gradle/caches/modules-2/files-2.1/org.openjfx/javafx-graphics/13/a9407212df2b75d557a509ec14a9e8e282494b4e/javafx-graphics-13.jar:/root/.gradle/caches/modules-2/files-2.1/org.openjfx/javafx-base/13/828b1e1a35104bb0f26a347c2716d553ca4cf4d2/javafx-base-13-linux.jar:/root/.gradle/caches/modules-2/files-2.1/org.openjfx/javafx-base/13/43c52e1d11b38514e9d2421ad98ca6a35de12b0/javafx-base-13.jar:/root/.gradle/caches/modules-2/files-2.1/uk.co.caprica/vlcj-natives/4.1.0/d45eb15ac25a1c085a365166d430435bd990409d/vlcj-natives-4.1.0.jar:/root/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-annotations/2.0.1/36e5996abe8655a6471b82af5ac1cd6786aecf85/jackson-annotations-2.0.1.jar:/root/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-core/2.0.1/481d14ec21e034ed45217c4854dbbf15940ce108/jackson-core-2.0.1.jar:/root/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/1.3.9/40719ea6961c0cb6afaeb6a921eaa1f6afd4cfdf/jsr305-1.3.9.jar:/root/.gradle/caches/modules-2/files-2.1/org.apache.httpcomponents/httpclient/4.0.1/1d7d28fa738bdbfe4fbd895d9486308999bdf440/httpclient-4.0.1.jar:/root/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/1.7.28/2cd9b264f76e3d087ee21bfc99305928e1bdb443/slf4j-api-1.7.28.jar:/root/.gradle/caches/modules-2/files-2.1/net.java.dev.jna/jna-platform/5.2.0/5520c6f3382801576547dd20854225ae2899b649/jna-platform-5.2.0.jar:/root/.gradle/caches/modules-2/files-2.1/net.java.dev.jna/jna/5.2.0/ed8b772eb077a9cb50e44e90899c66a9a6c00e67/jna-5.2.0.jar:/root/.gradle/caches/modules-2/files-2.1/org.apache.httpcomponents/httpcore/4.0.1/e813b8722c387b22e1adccf7914729db09bcb4a9/httpcore-4.0.1.jar:/root/.gradle/caches/modules-2/files-2.1/commons-logging/commons-logging/1.1.1/5043bfebc3db072ed80fbd362e7caf00e885d8ae/commons-logging-1.1.1.jar:/root/.gradle/caches/modules-2/files-2.1/commons-codec/commons-codec/1.3/fd32786786e2adb664d5ecc965da47629dca14ba/commons-codec-1.3.jar --patch-module main=/home/leonardo/Modelos/IdeaProjects/FullCam/Desktop/mosaico-desktop-v2/build/resources/main --module main/me.fullcam.mosaicov2.Main -Dfile.encoding=UTF-8 -Duser.country=BR -Duser.language=pt -Duser.variant main/me.fullcam.mosaicov2.Main
Successfully started process 'command '/usr/lib/jvm/java-12-oracle/bin/java''
/home/leonardo/Modelos/IdeaProjects/FullCam/Desktop/mosaico-desktop-v2/.
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:835)
Caused by: java.lang.NullPointerException: Location is required.
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3230)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)
        at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)
        at main/me.fullcam.mosaicov2.Main.start(Main.java:22)
        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:389)
        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 me.fullcam.mosaicov2.Main
:run (Thread[Task worker for ':',5,main]) completed. Took 0.574 secs.

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':run'.
> Process 'command '/usr/lib/jvm/java-12-oracle/bin/java'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 1s
5 actionable tasks: 5 executed

根據發布的MVCE 項目,這些是使項目工作所需的一些修改:

build.gradle

基於此:

plugins {
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
    id 'org.beryx.jlink' version '2.12.0'
}

group 'me.project.desktop'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'uk.co.caprica', name: 'vlcj', version: '4.2.0'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.0.1'
    compile group: 'com.google.http-client', name: 'google-http-client', version: '1.23.0'
    compile group: 'com.jfoenix', name: 'jfoenix', version: '8.0.9'
    compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.28'
}

javafx {
    version = "13"
    modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.base', 'javafx.graphics', 'javafx.media' ]
}

mainClassName = "me.project.mosaic.Main"

jlink {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'mosaico-desktop'
    }
}

所需的更改是:

  • 將 Java 級別設置為 11

  • 更新依賴項

JFoenix 設置為 8.0.9,適用於 Java 1.8。 如果你用 Java 11+ 運行,你會得到一個異常:

Caused by: java.lang.ClassNotFoundException: com.sun.javafx.css.converters.PaintConverter
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)

由於 JDK 9,CSS 轉換器是公共的 API,所以你需要 JFoenix for 9,比如 9.0.9。

請參閱此帖子以供參考。

  • 使用 JDK 11,而不是 12 或 13

JFoenix 的 JFXTextField 控件存在使用反射訪問私有 API 的長期問題

java.lang.IllegalAccessException: class com.jfoenix.skins.JFXTextFieldSkin cannot access a member of class javafx.scene.control.skin.TextFieldSkin (in module javafx.controls) with modifiers "private"
        at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:376)
...
java.lang.IllegalAccessException: class com.jfoenix.skins.JFXTextFieldSkin cannot access a member of class javafx.scene.control.skin.TextFieldSkin (in module javafx.controls) with modifiers "private"
        at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:376)
        at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:639)
...  

這會導致 null 指針異常:

Caused by: java.lang.NullPointerException
        at com.jfoenix.skins.JFXTextFieldSkin.updateTextPos(JFXTextFieldSkin.java:109)

與 Java 11 一起運行,它工作正常。

供參考,請參閱這篇文章

  • 添加出口

JFoenix 使用私有 API,所以它需要一堆導出,必須添加到 VM arguments,例如:

run {

    jvmArgs = [

        "--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED",

        "--add-exports=javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED",

        "--add-exports=javafx.base/com.sun.javafx.binding=ALL-UNNAMED",
        "--add-exports=javafx.graphics/com.sun.javafx.stage=ALL-UNNAMED",
        "--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED"
    ]

}

供參考,請參閱

這將是生成的build.gradle文件:

plugins {
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
    id 'org.beryx.jlink' version '2.12.0'
}

group 'me.project.desktop'
version '1.0-SNAPSHOT'

sourceCompatibility = 11

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'uk.co.caprica', name: 'vlcj', version: '4.2.0'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.0.1'
    compile group: 'com.google.http-client', name: 'google-http-client', version: '1.23.0'
    compile group: 'com.jfoenix', name: 'jfoenix', version: '9.0.9'
    compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.28'
}

javafx {
    version = "13"
    modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.base', 'javafx.graphics', 'javafx.media' ]
}

run {
    jvmArgs = ["--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED",
        "--add-exports=javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED",
        "--add-exports=javafx.base/com.sun.javafx.binding=ALL-UNNAMED",
        "--add-exports=javafx.graphics/com.sun.javafx.stage=ALL-UNNAMED",
        "--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED"
    ]
}

mainClassName = "me.project.mosaic.Main"

jlink {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'mosaico-desktop'
    }
}

運行(使用 JDK 11):

./gradlew clean run

將工作。

模塊化項目

為了運行jlink ,您需要創建一個模塊化描述符,例如:

module mosaic.viewer {
    requires javafx.controls;
    requires javafx.fxml;
    requires com.jfoenix;
    requires vlcj;
    requires jackson.annotations;
    requires jackson.databind;
    requires jackson.core;
    requires google.http.client;
    requires org.slf4j;
    requires jsr305;

    opens me.project.mosaic.login to javafx.fxml;
    exports me.project.mosaic;
}
  • 打開package

由於 FXML 使用反射,您必須使用控制器打開javafx.fxml模塊和包。 在這種情況下: opens me.project.mosaic.login to javafx.fxml; .

  • 添加出口

由於您現在有一個命名模塊,因此--add-exports現在設置為com.jfoenix而不是ALL-UNNAMED

運行(使用 JDK 11):

./gradlew clean jlink

將創建一個自定義圖像,您將能夠從啟動器腳本運行生成的圖像:

build/image/bin/mosaic-desktop

IDE

如果您從 IDE (IntelliJ) 而不是從終端運行項目,請確保使用 Gradle window 用於 IntelliJ 的任務,這將向您顯示項目和可用

重要的是在 Project Structure -> Project the project SDK 和語言級別設置為 11。

另外,Gradle window 有一個設置按鈕,點擊它,確保 Gradle Z18B5A217C4DAD256627DE3A0 也設置為 JDK 256662ZDE3A0。

您可以從此 window 運行:

  • 任務 -> 應用程序 -> 運行

  • 任務 -> 構建 -> jlink

最后,您還可以創建運行配置,但基於 Gradle,具有上述任務。

是的, Location is required異常意味着傳遞給FXMLLoader.load(...)方法的資源是null — 即不在您的類路徑中。

可能是您提供了錯誤的路徑,或者您使用了錯誤的類加載器,或者您在運行應用程序時錯誤配置了類路徑。 也許該文件在您的源文件夾中,但沒有被復制到類文件夾中?

從這里很難調試。 您需要確定該.fxml文件的位置並確保它位於類路徑中。

或者,您可以從文件中加載它。 例如

URL url = new File("C:/fxml/loginScene.fxml").toURI().toURL();
Parent root = FXMLLoader.load(url);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM