主方法不在模块内运行

5

我需要在模块内或者外运行main方法吗?

我刚开始接触Java的模块化系统。我正在尝试使用Java 10中的JavaFX编写一个简单的程序,因为Java 10是支持JavaFX的最新版本。

我在我的module-info.java中导入了JavaFX所需的依赖项,它会显示一个简单的窗口。

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)

有人能给我关于使用模块系统创建项目的建议或现实应用吗?
下面附上一对截图。
构建警告: enter image description here 运行时失败: enter image description here

请在发布问题之前仔细检查并修复任何错误。不要使用引号代替代码块或反之亦然。 - Maarten Bodewes
请将以下与编程有关的内容从英语翻译为中文。仅返回已翻译的文本,不要共享图像链接,而是在问题中包含图像。 - Naman
另一方面,将 module-info.java 代码添加到问题中也会使其更加清晰。 - Naman
3个回答

2
可能的嫌疑是您在module-info.java中使用com.main作为模块名称,而IDE抱怨在项目中找不到它。
我猜想,可以尝试在声明中使用com.gui作为模块名称来解决这个问题。

谢谢您的回复,第一个问题已经解决了,问题在于我之前测试时忘记删除com.main的限定导出。您对运行时失败有什么想法吗? - neth07
2
@neth07 我本来就预料到了,你能否现在更新问题并提供正确的 module-info.javasample.fxml 文件呢? - Naman

1
模块系统增加了更强的封装性。换句话说,不再是所有类都可以反射地访问到其他所有类。
以通常的方式启动JavaFX时,会为您实例化一个Application子类的实例。这是通过反射完成的,这意味着负责实例化子类的模块(javafx.graphics)必须具有反射访问所需的权限,以实例化具有公共、无参构造函数的公共类。为了授予此访问权限,包含Application子类的模块必须将适当的包exports至少到javafx.graphics
这在Application文档中有描述。

...

The Application subclass must be declared public and must have a public no-argument constructor.

...

Deploying an Application as a Module

If the Application subclass is in a named module then that class must be accessible to the javafx.graphics module. Otherwise, an exception will be thrown when the application is launched. This means that in addition to the class itself being declared public, the module must export (or open) the containing package to at least the javafx.graphics module.

For example, if com.foo.MyApplication is in the foo.app module, the module-info.java might look like this:

module foo.app {
    exports com.foo to javafx.graphics;
}

您似乎也在使用FXML。如果需要,您必须确保适当的包对javafx.fxml可进行反射访问(例如控制器类)。这在FXML介绍中有详细说明:

Deploying an Application as a Module

If FXMLLoader is used to load types in a named module, the application must ensure that all types that are referenced in the FXML files, including the controller class and any custom Node classes, are reflectively accessible to the javafx.fxml module. A type is reflectively accessible if the module opens the containing package to at least the javafx.fxml module.

For example, if com.foo.MyController is in the foo.app module, the module-info.java might look like this:

module foo.app {
    opens com.foo to javafx.fxml;
}

0

我通过以下步骤解决了这个问题:

需要 javafx 依赖的模块也要导出自己的内容,因为某些 javafx 包或模块需要这些模块。

例如:javafx.graphics

另外,请确保 fxml 资源文件是正确的。

1.) 更正 fxml 资源:

enter image description here

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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接