FXMLLoader.load() 在 java 9 之前的风格中工作正常,但在模块中失败
FXMLLoader.load() works fine in pre-java 9 style, but fails in modules
我成功制作了一个简单的 JavaFX FXML 程序(采用 Java 9 之前的样式,不是模块)
我使用了 3 个文件和主要 class 如下:
└───javafxfxmldemo
FXMLDocument.fxml
FXMLDocumentController.java
JavaFXFXMLDemo.java
主要class
public class JavaFXFXMLDemo extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
它在 NetBeans 9 和带有 javac 和 java.
的 DOS 终端中都能完美运行
现在,我尝试在 Java 个模块中制作相同的程序。下面是我的源代码结构:
└───src
└───com.fxmlapp
│ module-info.java
│
└───com
└───fxmlapp
FXEventModuleDemo.java
FXMLDocument.fxml
FXMLDocumentController.java
模块-info.java
module com.fxmlapp {
requires javafx.controls;
requires javafx.fxml;
exports com.fxmlapp;
}
除主要 class 名称外,其余所有代码均相同。
它在 NetBeans 9 中编译,我也可以在 DOS 终端中编译,如下所示:
javac -d mods\com.fxmlapp --module-path %PATH_TO_FX% src\com.fxmlapp\module-info.java src\com.fxmlapp\com\fxmlapp\FXEventModuleDemo.java src\com.fxmlapp\com\fxmlapp\FXMLDocumentController.java
编译后,我把FXMLDocument.fxml文件放在mods目录下,如下图
├───mods
│ └───com.fxmlapp
│ │ module-info.class
│ │
│ └───com
│ └───fxmlapp
│ FXEventModuleDemo.class
│ FXMLDocument.fxml
│ FXMLDocumentController.class
│
└───src
└───com.fxmlapp
│ module-info.java
│
└───com
└───fxmlapp
FXEventModuleDemo.java
FXMLDocument.fxml
FXMLDocumentController.java
但是,它失败了运行。我在 NetBeans 9 和 DOS 终端中都尝试过,如下所示:
java --module-path %PATH_TO_FX%;mods -m com.fxmlapp/com.fxmlapp.FXEventModuleDemo
错误来自语句:
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
我知道,这个问题有很多帖子,但是当 java 模块发生错误时,我找不到解决这个问题的方法。我不认为这是文件位置问题,因为下面的语句有效。
System.out.println(getClass().getResource("FXMLDocument.fxml"));
FXMLLoader.load() 似乎在模块中不起作用。
如果它适用于非模块风格,我相信它也必须适用于模块。
实际报错信息如下;是的,我看到很多关于此错误的问题,但我仍然找不到 java 模块的解决方案)我的模块 info.java 或我的编译或 [=66= 做错了吗? ] 命令?
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:566)
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:566)
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(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javafx.fxml.LoadException:
/D:/OpenJFX_Demo/FXEventModuleDemo/mods/com.fxmlapp/com/fxmlapp/FXMLDocument.fxml:14
at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3237)
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 com.fxmlapp/com.fxmlapp.FXEventModuleDemo.start(FXEventModuleDemo.java:13)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop(WinApplication.java:174)
... 1 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private javafx.scene.control.Label com.fxmlapp.FXMLDocumentController.label accessible: module com.fxmlapp does not "opens com.fxmlapp" to module javafx.fxml
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:176)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:170)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.addAccessibleFields(FXMLLoader.java:3479)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.access00(FXMLLoader.java:3328)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.run(FXMLLoader.java:3444)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.run(FXMLLoader.java:3440)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.addAccessibleMembers(FXMLLoader.java:3439)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.getControllerFields(FXMLLoader.java:3378)
at javafx.fxml/javafx.fxml.FXMLLoader.injectFields(FXMLLoader.java:1170)
at javafx.fxml/javafx.fxml.FXMLLoader.access00(FXMLLoader.java:105)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processValue(FXMLLoader.java:865)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:759)
at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
... 17 more
Exception running application com.fxmlapp.FXEventModuleDemo
如@nullpointer所解释:
错误说 模块 com.fxmlapp 没有 "opens com.fxmlapp" 到模块 javafx.fxml.
所以,我添加了--add-opens com.fxmlapp/com.fxmlapp=javafx.fxml。它解决了问题。
我成功制作了一个简单的 JavaFX FXML 程序(采用 Java 9 之前的样式,不是模块) 我使用了 3 个文件和主要 class 如下:
└───javafxfxmldemo
FXMLDocument.fxml
FXMLDocumentController.java
JavaFXFXMLDemo.java
主要class
public class JavaFXFXMLDemo extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
它在 NetBeans 9 和带有 javac 和 java.
的 DOS 终端中都能完美运行现在,我尝试在 Java 个模块中制作相同的程序。下面是我的源代码结构:
└───src
└───com.fxmlapp
│ module-info.java
│
└───com
└───fxmlapp
FXEventModuleDemo.java
FXMLDocument.fxml
FXMLDocumentController.java
模块-info.java
module com.fxmlapp {
requires javafx.controls;
requires javafx.fxml;
exports com.fxmlapp;
}
除主要 class 名称外,其余所有代码均相同。
它在 NetBeans 9 中编译,我也可以在 DOS 终端中编译,如下所示:
javac -d mods\com.fxmlapp --module-path %PATH_TO_FX% src\com.fxmlapp\module-info.java src\com.fxmlapp\com\fxmlapp\FXEventModuleDemo.java src\com.fxmlapp\com\fxmlapp\FXMLDocumentController.java
编译后,我把FXMLDocument.fxml文件放在mods目录下,如下图
├───mods
│ └───com.fxmlapp
│ │ module-info.class
│ │
│ └───com
│ └───fxmlapp
│ FXEventModuleDemo.class
│ FXMLDocument.fxml
│ FXMLDocumentController.class
│
└───src
└───com.fxmlapp
│ module-info.java
│
└───com
└───fxmlapp
FXEventModuleDemo.java
FXMLDocument.fxml
FXMLDocumentController.java
但是,它失败了运行。我在 NetBeans 9 和 DOS 终端中都尝试过,如下所示:
java --module-path %PATH_TO_FX%;mods -m com.fxmlapp/com.fxmlapp.FXEventModuleDemo
错误来自语句:
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
我知道,这个问题有很多帖子,但是当 java 模块发生错误时,我找不到解决这个问题的方法。我不认为这是文件位置问题,因为下面的语句有效。
System.out.println(getClass().getResource("FXMLDocument.fxml"));
FXMLLoader.load() 似乎在模块中不起作用。
如果它适用于非模块风格,我相信它也必须适用于模块。
实际报错信息如下;是的,我看到很多关于此错误的问题,但我仍然找不到 java 模块的解决方案)我的模块 info.java 或我的编译或 [=66= 做错了吗? ] 命令?
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:566)
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:566)
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(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javafx.fxml.LoadException:
/D:/OpenJFX_Demo/FXEventModuleDemo/mods/com.fxmlapp/com/fxmlapp/FXMLDocument.fxml:14
at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3237)
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 com.fxmlapp/com.fxmlapp.FXEventModuleDemo.start(FXEventModuleDemo.java:13)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop(WinApplication.java:174)
... 1 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private javafx.scene.control.Label com.fxmlapp.FXMLDocumentController.label accessible: module com.fxmlapp does not "opens com.fxmlapp" to module javafx.fxml
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:176)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:170)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.addAccessibleFields(FXMLLoader.java:3479)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.access00(FXMLLoader.java:3328)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.run(FXMLLoader.java:3444)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.run(FXMLLoader.java:3440)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.addAccessibleMembers(FXMLLoader.java:3439)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.getControllerFields(FXMLLoader.java:3378)
at javafx.fxml/javafx.fxml.FXMLLoader.injectFields(FXMLLoader.java:1170)
at javafx.fxml/javafx.fxml.FXMLLoader.access00(FXMLLoader.java:105)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processValue(FXMLLoader.java:865)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:759)
at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
... 17 more
Exception running application com.fxmlapp.FXEventModuleDemo
如@nullpointer所解释:
错误说 模块 com.fxmlapp 没有 "opens com.fxmlapp" 到模块 javafx.fxml.
所以,我添加了--add-opens com.fxmlapp/com.fxmlapp=javafx.fxml。它解决了问题。