【发布时间】:2017-04-18 03:49:39
【问题描述】:
我一直在用 Java 编写自己的一个小项目,最近,我编译它并收到此错误:
线程“main”java.lang.IllegalAccessError 中的异常:超类访问检查失败: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 参数是否有问题,但我不知道如何以不同的方式编译我的代码来反映这一点。如果有人知道如何更改我得到的导出代码,请告诉我。
无论如何,我想知道的是我的代码的哪一部分是由这个异常引起的,以及我该如何解决它。
【问题讨论】:
-
看起来您正在使用 Java 9 进行编译。如果 Java 9 中没有您需要的任何内容,您可以使用 Java 8 对其进行测试吗?
-
我认为这是因为它试图使用我认为是 JDK 模块之一的
javafx.base。希望更改编译器版本可以修复它,因为我对模块几乎一无所知,还没有进一步帮助。 -
没问题,让我知道会发生什么!如果您还没有 Java 8,则可能需要下载它。
-
太棒了 :) 我刚刚做到了,谢谢!
-
@YorickIsTheBest 一旦你在 Java 9 上编译或者有人在上面启动你的应用程序,这个问题就会重新出现。请参阅this answer 以获得正确的修复。