我一直在做一个自己的Java小项目,最近,我编译了它,收到了这个错误:
线程“main”中出现异常java.lang. IllegalList错误:超类访问检查失败:类kröw.zeale.v1.program.core.DataManager$ConstructList(在未命名模块@0x4563e9ab中)无法访问类com.sun.javafx.collections.ObservableListWrapper(在模块javafx.base中),因为模块javafx.base未将com.sun.javafx.collections导出到未命名模块@0x4563e9ab
背景:
所以,我目前有三个不同的类,都在同一个包中。我的层次结构如下:
• Kröw
• DataManager
♦ ConstructList
字符串
在我的程序的以前版本中,我的层次结构是这样的:
• Kröw
♦ DataManager
- ConstructList
型
在这两种情况下,ConstructList
都扩展了com.sun.javafx.collections.ObservableListWrapper<Construct>
(我不认为Construct
类在这里是必要的,我宁愿不显示它,但如果需要的话,我可以这样做)。
无论如何,现在,我的IDE可以按预期运行应用程序,但是,当我导出它时,上面的异常给了我。
全栈跟踪:
Exception in thread "main" java.lang.IllegalAccessError: superclass access check failed: class kröw.zeale.v1.program.core.DataManager$ConstructList (in unnamed module @0x4563e9ab) cannot access class com.sun.javafx.collections.ObservableListWrapper (in module javafx.base) because module javafx.base does not export com.sun.javafx.collections to unnamed module @0x4563e9ab
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(Unknown Source)
at java.base/java.security.SecureClassLoader.defineClass(Unknown Source)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(Unknown Source)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(Unknown Source)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(Unknown Source)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
at kröw.zeale.v1.program.core.DataManager.<init>(DataManager.java:22)
at kröw.zeale.v1.program.core.DataManager.getDataManager(DataManager.java:63)
at kröw.zeale.v1.program.core.Kröw.<clinit>(Kröw.java:23)
型
错误中提到的Kröw
类的一部分:
private static final DataManager DATA_MANAGER = DataManager.getDataManager(); // line 23
型
错误中提到的DataManager
类的部分:
static DataManager getDataManager() { // line 66
return new DataManager();
}
型
和
public final ConstructList constructs = new ConstructList(); // line 22
型
ConstructList
类:
public class ConstructList extends ObservableListWrapper<Construct> { // line 209
private ConstructList() {
super(new ArrayList<>()); // line 212
}
public LinkedList<Construct> getDeadConstructs() {
...
}
public LinkedList<Construct> getLivingConstructs() {
...
}
}
型
现在,我已经查看了可以找到的资源,例如IllegalAccessError SO Question
(* 注意这里是如何说的:“试图访问方法”而不是“超类访问检查失败”*)
这个解决方案的公认答案是检查编译后的jar文件和我的源代码之间是否有什么不同,所以我尝试了一下,发现了一些微小的差异。下面是我反编译后的jar文件中更改的代码行。(使用JD-GUI反编译)
DataManager
类:
public final ConstructList constructs = new ConstructList(null);
型
- 曾经是 *
public final ConstructList constructs = new ConstructList();
型
ConstructList
类:
private ConstructList() {
super();
}
型
- 曾经是 *
private ConstructList() {
super(new ArrayList<>());
}
型
现在,在反编译的代码中,ConstructList()
构造函数没有任何参数,我看到它被传入null
调用,这对我来说看起来像是一个错误,但我不确定这是否是我的异常的原因,我无法通过互联网找到任何东西,这就是我来这里的原因。
另一方面,我给出的反编译代码是由我的IDE使用其导出功能创建的。我想看看我的构造函数的null
参数是否有问题,但我不知道如何以不同的方式编译我的代码来反映这一点。如果有人知道如何更改我得到的导出代码,请通知我。
无论如何,**我想知道的是 * 这个异常是由我的代码的哪一部分引起的,以及我如何修复它。
6条答案
按热度按时间ct2axkht1#
问题源于Java 9模块系统,它强烈封装了JDK内部API,以及您使用的JDK内部API,即
ObservableListWrapper
(您可以告诉它是内部的,因为包名以com.sun
开头)。如果您或您的用户通过编译或运行Java 9,则此错误将持续存在。正确的解决方法是停止使用
ObservableListWrapper
。根据this presentation (PDF)判断,您应该使用theFXCollections
utility class(update:FXCollections
in OpenJFX 11)。如果这对你不起作用,还有一个变通方法:将
--add-exports javafx.base/com.sun.javafx.collections=ALL-UNNAMED
添加到compile(javac
)* 和 * launch(java
)命令中。ojsjcaue2#
JavaFX是JDK 9中的一组模块,javadoc在这里:http://download.java.net/java/jdk9/jfxdocs/overview-summary.html
base模块是基础API,如果查看javadoc中列出的包,则不会看到com.sun.javafx.collections。(非出口)javafx.base模块。JavaFX之外的任何东西都不应该使用它。当然,你可以使用命令行选项来解决这个问题,但我认为你必须看看它的用法,才能理解为什么它试图使用一个JavaFX内部类。一旦删除了对内部类的依赖,那么我假设应用程序应该像以前一样工作。
3phpmpom3#
原来你是用Java 9编译的,它利用了JDK的新
module
系统。可能有一种有效的方法可以通过实现模块来解决你的问题,但是另一种解决方案是简单地用Java 8编译!cgyqldqp4#
我想你已经回答了你自己的问题。如果你更新你的jar包,包含一些小的差异,这个错误可能就不会出现了。
twh00eeo5#
第一个月
.另一个解决方案是简单地使用Java 8编译!
我可以通过将Java 11编译器切换到Code Level 8并将
public static void main(String[] args ...)
移动到非FX类并在那里构建我的JavaFXApplication
来避免这种情况。这应该工作吗?这是一个bug吗?我正在使用OpenJDK 11进行编译,但使用的是语言级别8。如果没有这种解决方法,我会在IntelliJ中抛出异常,所以如果语言级别8应该自然地抑制它,它可能只是IDE的细微差别。
bvpmtnay6#
Java 17不允许访问JDK的内部部分。反射和调用内部API都不允许。
下面这篇文章对理解和解决这个问题非常有用。
https://community.axonivy.com/d/368-inaccessibleobjectexception-and-illegalaccesserror-with-java-17
文章中提到的这个解决方案可以派上用场: