我需要在模块内部还是外部运行main
方法?
我是使用Java模块化系统的新手。我正在尝试使用Java 10中的JavaFX创建一个简单的程序,因为它是支持JavaFX的Java的最新版本。
我为JavaFX导入了module-info.java
上必需的依赖项,该依赖项仅显示一个简单的窗口。
sample.fxml
代码:
<?import javafx.scene.layout.GridPane?>
<GridPane fx:controller="com.gui.Controller"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
</GridPane>
构建代码时,它会显示:
Warning:(4, 27) java: module not found: com.main
当我尝试运行我的代码时,我得到:
Exception in Application constructor Exception in thread "main" 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:564)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:941)
有人可以给我建议吗,或者以某种方式为我提供有关使用模块化系统创建项目的实际应用建议。
我在下面附有一对屏幕截图。
构建警告:
运行时失败:
答案 0 :(得分:2)
这里可能引起怀疑,是您在com.main
中使用module-info.java
作为模块名称,IDE抱怨在项目中找不到该名称。
我想,可以使用com.gui
作为声明中的模块名称来解决此问题。
答案 1 :(得分:1)
模块系统增加了更强的封装性。换句话说,不再是所有其他类都可以反射地访问所有类。
以常规方式启动JavaFX时,将为您实例化Application
子类的实例。这是通过反射完成的,这意味着负责实例化子类(javafx.graphics
)的模块必须具有使用公共无参数构造函数实例化公共类所必需的反射访问。要授予此访问权限,包含Application
子类的模块必须exports
至少要 javafx.graphics
的适当包。
这在Application
的{{3}}中进行了描述:
...
Application
子类必须声明为public,并且必须具有公共的无参数构造函数。...
将应用程序部署为模块
如果
Application
子类在命名模块中,则javafx.graphics
模块必须可以访问该类。否则,启动应用程序时将引发异常。这意味着,除了将类本身声明为公共类之外,该模块还必须将包含的包导出(或打开)到至少javafx.graphics
模块中。例如,如果
com.foo.MyApplication
在foo.app
模块中,则module-info.java
可能看起来像这样:module foo.app { exports com.foo to javafx.graphics; }
您似乎也正在使用FXML。如有必要,您必须确保javafx.fxml
可以反射地访问相应的程序包(例如,控制器类)。 the documentation中对此进行了记录:
将应用程序部署为模块
如果使用
FXMLLoader
来加载命名模块中的类型,则应用程序必须确保FXML文件中引用的所有类型(包括控制器类和任何自定义Node
类)都具有反射性javafx.fxml
模块可以访问。如果模块opens
至少包含javafx.fxml
模块的包,则该类型可以反射访问。例如,如果
com.foo.MyController
在foo.app
模块中,则module-info.java
可能看起来像这样:module foo.app { opens com.foo to javafx.fxml; }
答案 2 :(得分:0)
我通过确保解决此问题:
需要javafx依赖项的模块也会导出自身 导致某些javafx软件包或模块需要需要它的模块。
例如javafx.graphics
还要确保fxml资源正确。
1。)对fxml资源的修正:
2。)导出需要javafx依赖项的模块:
错误:(读取)
Caused by: java.lang.IllegalAccessException: class com.sun.javafx.application.LauncherImpl (in module javafx.graphics) cannot access class com.gui.GUI (in module com.gui) because module com.gui does not export com.gui to module javafx.graphics
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:360)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:589)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:479)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:875)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
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$3(WinApplication.java:175)
解决方案:module-info.java
module com.gui {
requires javafx.graphics;
requires javafx.fxml;
exports com.gui;
}