我有一个非常基本的JavaFX应用程序,如果应用程序类不是主类,它可以完美无缺地工作:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
public class Main {
public static void main(String[] args) {
Application.launch(App.class, args);
}
}
public class App extends Application {
@Override
public void start(Stage primaryStage) {
FXMLLoader loader = new FXMLLoader(); // works
}
}
但是,当我将两者合并在一起时(这是大多数html" target="_blank">教程,包括OpenJFX的官方文档中推荐的方式),模块系统会抛出illegalAccessErr
(至少在OpenJDK 11.0.2上):
public class MainApp extends Application {
@Override
public void start(Stage primaryStage) {
FXMLLoader loader = new FXMLLoader(); // throws IllegalAccessError
}
public static void main(String[] args) {
launch(MainApp.class, args);
}
}
例外情况是:
java.lang.IllegalAccessError:类com.sun.javafx.fxml.fxmlLoaderHelper
(在未命名的模块@0x642C1A1B
中)无法访问类com.sun.javafx.util.utils
(在模块javafx.graphics
中),因为模块javafx.graphics
不会将com.sun.javafx.util
导出到未命名的模块
奇怪的是,我没有积极地使用模块系统。我没有在我的项目中添加module-info.java
。所以我假设所有的东西都应该导出到任何未命名的模块?但这根本不是重点。
主要的问题是:为什么相同的代码如果分布在两个类中会有不同的行为?在这两种情况下,fxmlloader
都使用com.sun.javafx.fxml.fxmlloaderhelper
,后者又使用com.sun.javafx.util.utils
。所以我要么在两种情况下都得到异常,要么在无情况下得到异常。有什么区别呢?
有一些答案已经张贴,可以部分适用于您的问题,但它可能是方便的收集他们在这里,并提出他们在一个完整的答案。
应用程序类
在对Maven Shade JavaFX运行时组件缺失的回答中,我解释了当您使用application
类作为主类时,希望您使用模块系统的原因。
这个错误来自java.base模块(链接)中的sun.launcher.launcherHelper
。
如果主应用程序扩展了application
并具有main
方法,LauncherHelper
将检查javafx.graphics
模块是否作为命名模块出现:
Optional<Module> om = ModuleLayer.boot().findModule(JAVAFX_GRAPHICS_MODULE_NAME);
if (!om.isPresent()) {
abort(null, "java.launcher.cls.error5");
}
如果该模块不存在,则中止发射。
但是,如果不通过application
类运行,则不会进行该检查。
主类
对于Maven和Eclipse之间启动JavaFX11应用程序的不同行为的另一个答案解释了当您使用Launcher
类(一个不扩展应用程序的主类)和Mavenexec:java
插件时,它在没有模块化系统的情况下工作的原因。
如果在运行main.main()
时检查命令行:
/path/to/jdk-11.0.2.jdk/Contents/Home/bin/java \
"-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=60556:/Applications/IntelliJ IDEA.app/Contents/bin" \
-Dfile.encoding=UTF-8 \
-classpath /path/to/so-question-54756176-master/target/classes:/path/to/.m2/repository/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2.jar:.../path/to/.m2/repository/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2-mac.jar \
Main
JavaFX SDK中的所有JavaFX JAR都被添加到类路径中,您正在运行经典的java-cp...main
。
缺少javafx.fxml
Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module @0x5fce9dc5) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module @0x5fce9dc5
at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38)
at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056)
您的错误显示您正在使用FXML,但它无法在module-path中解析,因此它试图通过反射访问,但由于您没有将javafx.graphics
打开到未命名的模块,因此失败。
所以现在您会问:我一开始就没有设置javafx.graphics
!
好吧,你没有,但IntelliJ为你做的!
/path/to/jdk-11.0.2.jdk/Contents/Home/bin/java \
--add-modules javafx.base,javafx.graphics \
--add-reads javafx.base=ALL-UNNAMED \
--add-reads javafx.graphics=ALL-UNNAMED \
"-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=60430:/Applications/IntelliJ IDEA.app/Contents/bin" \
-Dfile.encoding=UTF-8 \
-classpath /path/to/so-question-54756176-master/target/classes:/path/to/.m2/repository/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2.jar:.../.m2/repository/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-mac.jar \
MainApp
您可以看到IntelliJ默认添加javafx.base
和javafx.graphics
。因此只缺少javafx.fxml
(然后当然应该添加module-path)。
正如您所指出的,推荐的解决方案在文档中:
或者在命令行上,使用--module-path
包含JavaFX SDK库文件夹的路径,在这种情况下使用--add-module
包含JavaFX.fxml
(您没有控件)。
或者使用Maven插件。在某个时候,您将不得不离开IDE,因此您将需要使用插件来运行应用程序。
Maven exec
关于Mavenexec
插件的最后一点注意事项,以备您使用:
此外,在模块化系统的插件exec:java
被修复之前,推荐的Maven解决方案将使用exec:exec
,如本期所述,因此您可以指定两个vm参数。
问题内容: 说,我有以下mixin通过触摸彼此重叠: 如果我希望我的视图通过该命令,请检查A->检查B,我的代码应该是还是? 为什么我们总是将其子类或子类放在mixins之后?(我通过阅读django通用视图的源代码注意到了这一点,但我不知道其背后的原理,如果有的话) 问题答案: MRO基本上是深度优先,从左到右。有关更多信息,请参见新型Python类中的方法解析顺序(MRO)。 你可以查看要检查
我知道线程是并发运行的,所以您无法预测执行的顺序,但在提供的代码中,我在运行其他代码之前加入了thread。如果应该等到线程执行完毕,那么为什么顺序仍然是随机的呢?在两个print语句之前加入任何内容总是会导致它们最后被打印,而如果我在之后加入所有内容,它并不总是最后,为什么?
问题内容: 是否可以定义默认情况下在哪个架构中创建新表?(由“不合格的表名”引用。) 我已经在Postgres中看到了有关使用“搜索路径”的一些详细信息,但是我认为它仅在检索数据而不是创建时才起作用。 我有一堆SQL脚本,它们创建许多表。我不想修改脚本,而是希望在默认模式下将数据库创建表设置为特定的模式-当它们具有非限定名称时。 这可能吗? 问题答案: 搜索路径的确是您想要的:
我想知道为什么“k”和“a”的结果不同。唯一的区别是,我在创建k时添加了一对额外的括号。我认为结果应该是一样的。我的环境是Eclipse EE 2021,JDK17。如果您能分享您的观点,我们将不胜感激。 结果:
问题内容: 以下两个查询有什么区别? 问题答案: 在SQL方面,绝对没有区别:这两个查询完全相同。 (您可以通过回显它们进行检查) 是的更完整的语法,允许使用: 有关更多信息,您应该阅读手册的 变量解析/复杂(curly)语法 部分 (引用几句话) : 之所以称其为“复杂”,是因为语法复杂,而是因为它允许使用复杂的表达式。 可以通过此语法包括具有字符串表示形式的任何标量变量,数组元素或对象属性。
本文向大家介绍物联网如何影响大数据,包括了物联网如何影响大数据的使用技巧和注意事项,需要的朋友参考一下 当涉及到当今最受关注的两种技术时,大数据和物联网(IoT)可能正处于主导地位。在过去的几年中,大数据在许多领域都取得了进步。尽管物联网恰好与众不同,但它已与大数据紧密相连。 什么是大数据? 大数据本质上是大量复杂形式的数据。具体来说,它还涉及使用预测分析和方法,这些方法和方法可从此类数据中提取有