Java, IllegalAccessorError: superclass access check failed
Java, IllegalAccessorError: superclass access check failed
我一直在 Java 做我自己的一个小项目,最近,我编译它并收到这个错误:
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
背景:
所以,我目前有三个不同的 classes,都在同一个包中。我的层次结构如下:
• Kröw
• DataManager
♦ ConstructList
在我以前的程序版本中,我的层次结构是这样的:
• Kröw
♦ DataManager
- ConstructList
在这两种情况下,ConstructList
扩展了 com.sun.javafx.collections.ObservableListWrapper<Construct>
。 (我认为 class 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)
部分classKröw
错误中提到的:
private static final DataManager DATA_MANAGER = DataManager.getDataManager(); // line 23
部分 class DataManager
中提到的错误:
static DataManager getDataManager() { // line 66
return new DataManager();
}
和
public final ConstructList constructs = new ConstructList(); // line 22
Class 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
(注意这是怎么说的:"tried to access method" 而不是 "superclass access check failed")
该解决方案的可接受答案是检查编译的 jar 文件和我的源代码之间是否有任何不同,所以我尝试了这个并发现了一些细微差别。这是我反编译的 jar 文件中更改的代码行。 (使用JD-GUI反编译)
Class DataManager
:
public final ConstructList constructs = new ConstructList(null);
曾经是:
public final ConstructList constructs = new ConstructList();
Class ConstructList
:
private ConstructList() {
super();
}
曾经是:
private ConstructList() {
super(new ArrayList<>());
}
现在,在反编译的代码中,ConstructList()
构造函数没有任何参数,我看到它被调用时传入了 null
,这对我来说似乎是一个错误,但是我不确定这是否是我异常的原因,我无法通过互联网找到任何东西,这就是我来到这里的原因。
另一方面,我给出的反编译代码是由我的 IDE 使用其导出功能创建的。我想看看我的构造函数的 null
参数是否是问题所在,但我不知道如何以不同的方式编译我的代码以反映这一点。如果有人知道如何更改我得到的导出代码,请告诉我。
无论如何,我想知道的是这个异常是由我的代码的哪一部分引起的,以及我该如何解决它。
我想你已经回答了你自己的问题。如果您更新包含细微差异的 jar,错误可能会消失。
原来你是用 Java 9 编译的,它利用了 JDK 的新 module
系统。可能有一种通过实施模块来解决问题的有效方法,但是另一种解决方案是简单地使用 Java 8!
进行编译
问题出在 Java 9 模块系统,即 strongly encapsulates JDK-internal APIs,以及您使用 JDK-内部 API,即 ObservableListWrapper
(你可以看出它是内部的,因为包名称以 com.sun
开头)。如果您或您的用户通过编译或 运行 使用 Java 9,此错误将持续存在。
正确的解决方法是停止使用 ObservableListWrapper
。根据 this presentation (PDF), you should be using the FXCollections
utility class (update: FXCollections
in OpenJFX 11) 判断。
如果这对您不起作用,还有一个解决方法。添加 --add-exports javafx.base/com.sun.javafx.collections=ALL-UNNAMED
到编译 (javac
) 和 启动 (java
) 命令。
JavaFX是JDK9中的一组模块,javadoc在这里:
http://download.java.net/java/jdk9/jfxdocs/overview-summary.html
javafx.base 模块是基础 API,如果您查看 javadoc 中列出的包,您将看不到 com.sun.javafx.collections。这是因为该包是 javafx.base 模块的内部(未导出)。 JavaFX 之外的任何东西都不应使用它。您当然可以使用命令行选项来解决此问题,但我认为您必须查看用法以了解它为什么尝试使用 JavaFX 内部 class。一旦删除了对内部 class 的依赖,我认为应用程序应该像以前一样工作。
IllegalAccessorError: superclass access check failed
... another solution is to simply compile with Java 8!
我可以通过将我的 Java 11 编译器切换到代码级别 8 和 将 public static void main(String[] args ...)
移动到非 FX [=23] 来避免这种情况=] 并在那里构建我的 JavaFX Application
)。
这应该行得通吗?这是一个错误吗?我正在使用 AdoptOpenJDK 11 进行编译,但使用的是语言级别 8。如果没有这种解决方法,异常会在 IntelliJ 中为我抛出,因此 if 语言级别 8 应该自然地抑制它,它可能只是IDE.
的细微差别
我一直在 Java 做我自己的一个小项目,最近,我编译它并收到这个错误:
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
背景:
所以,我目前有三个不同的 classes,都在同一个包中。我的层次结构如下:
• Kröw
• DataManager
♦ ConstructList
在我以前的程序版本中,我的层次结构是这样的:
• Kröw
♦ DataManager
- ConstructList
在这两种情况下,ConstructList
扩展了 com.sun.javafx.collections.ObservableListWrapper<Construct>
。 (我认为 class 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)
部分classKröw
错误中提到的:
private static final DataManager DATA_MANAGER = DataManager.getDataManager(); // line 23
部分 class DataManager
中提到的错误:
static DataManager getDataManager() { // line 66
return new DataManager();
}
和
public final ConstructList constructs = new ConstructList(); // line 22
Class 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
(注意这是怎么说的:"tried to access method" 而不是 "superclass access check failed")
该解决方案的可接受答案是检查编译的 jar 文件和我的源代码之间是否有任何不同,所以我尝试了这个并发现了一些细微差别。这是我反编译的 jar 文件中更改的代码行。 (使用JD-GUI反编译)
Class DataManager
:
public final ConstructList constructs = new ConstructList(null);
曾经是:
public final ConstructList constructs = new ConstructList();
Class ConstructList
:
private ConstructList() {
super();
}
曾经是:
private ConstructList() {
super(new ArrayList<>());
}
现在,在反编译的代码中,ConstructList()
构造函数没有任何参数,我看到它被调用时传入了 null
,这对我来说似乎是一个错误,但是我不确定这是否是我异常的原因,我无法通过互联网找到任何东西,这就是我来到这里的原因。
另一方面,我给出的反编译代码是由我的 IDE 使用其导出功能创建的。我想看看我的构造函数的 null
参数是否是问题所在,但我不知道如何以不同的方式编译我的代码以反映这一点。如果有人知道如何更改我得到的导出代码,请告诉我。
无论如何,我想知道的是这个异常是由我的代码的哪一部分引起的,以及我该如何解决它。
我想你已经回答了你自己的问题。如果您更新包含细微差异的 jar,错误可能会消失。
原来你是用 Java 9 编译的,它利用了 JDK 的新 module
系统。可能有一种通过实施模块来解决问题的有效方法,但是另一种解决方案是简单地使用 Java 8!
问题出在 Java 9 模块系统,即 strongly encapsulates JDK-internal APIs,以及您使用 JDK-内部 API,即 ObservableListWrapper
(你可以看出它是内部的,因为包名称以 com.sun
开头)。如果您或您的用户通过编译或 运行 使用 Java 9,此错误将持续存在。
正确的解决方法是停止使用 ObservableListWrapper
。根据 this presentation (PDF), you should be using the FXCollections
utility class (update: FXCollections
in OpenJFX 11) 判断。
如果这对您不起作用,还有一个解决方法。添加 --add-exports javafx.base/com.sun.javafx.collections=ALL-UNNAMED
到编译 (javac
) 和 启动 (java
) 命令。
JavaFX是JDK9中的一组模块,javadoc在这里: http://download.java.net/java/jdk9/jfxdocs/overview-summary.html
javafx.base 模块是基础 API,如果您查看 javadoc 中列出的包,您将看不到 com.sun.javafx.collections。这是因为该包是 javafx.base 模块的内部(未导出)。 JavaFX 之外的任何东西都不应使用它。您当然可以使用命令行选项来解决此问题,但我认为您必须查看用法以了解它为什么尝试使用 JavaFX 内部 class。一旦删除了对内部 class 的依赖,我认为应用程序应该像以前一样工作。
IllegalAccessorError: superclass access check failed
... another solution is to simply compile with Java 8!
我可以通过将我的 Java 11 编译器切换到代码级别 8 和 将 public static void main(String[] args ...)
移动到非 FX [=23] 来避免这种情况=] 并在那里构建我的 JavaFX Application
)。
这应该行得通吗?这是一个错误吗?我正在使用 AdoptOpenJDK 11 进行编译,但使用的是语言级别 8。如果没有这种解决方法,异常会在 IntelliJ 中为我抛出,因此 if 语言级别 8 应该自然地抑制它,它可能只是IDE.
的细微差别