[英]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。
請參閱此帖子以供參考。
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;
}
由於 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.