Java,IllegalAccessorError:超类访问检查失败

Krö*_*röw 3 java java-9

我一直在用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
Run Code Online (Sandbox Code Playgroud)

在我的程序的早期版本中,我的层次结构是这样的:

• Kröw
   ? DataManager
      - ConstructList
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,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)
Run Code Online (Sandbox Code Playgroud)

Kröw错误中提到的类的一部分:

private static final DataManager DATA_MANAGER = DataManager.getDataManager(); // line 23
Run Code Online (Sandbox Code Playgroud)

DataManager错误中提到的类的部分:

static DataManager getDataManager() { // line 66
    return new DataManager();
}
Run Code Online (Sandbox Code Playgroud)

public final ConstructList constructs = new ConstructList();  // line 22
Run Code Online (Sandbox Code Playgroud)

课程ConstructList:

public class ConstructList extends ObservableListWrapper<Construct> { // line 209

    private ConstructList() {
        super(new ArrayList<>()); // line 212
    }

   public LinkedList<Construct> getDeadConstructs() {
      ...
   }

   public LinkedList<Construct> getLivingConstructs() {
      ...
   }
}
Run Code Online (Sandbox Code Playgroud)

现在,我已经查看了我可以找到的资源,例如IllegalAccessError SO Question

(注意这是怎么说的:"试图访问方法"而不是"超类访问检查失败")

该解决方案的公认答案是检查编译的jar文件和源代码之间是否有任何不同,所以我尝试了一下,发现了一些细微差别.以下是我的反编译jar文件中更改的代码行.(使用JD-GUI进行编译)

课程DataManager:

public final ConstructList constructs = new ConstructList(null);
Run Code Online (Sandbox Code Playgroud)

以前是:

public final ConstructList constructs = new ConstructList();
Run Code Online (Sandbox Code Playgroud)

课程ConstructList:

private ConstructList() {
  super();
}
Run Code Online (Sandbox Code Playgroud)

以前是:

private ConstructList() {
   super(new ArrayList<>());
}
Run Code Online (Sandbox Code Playgroud)

现在,在反编译的代码中,ConstructList()构造函数没有任何参数,我看到它被null传入调用,这对我来说看起来像是一个错误,但我不确定它是否是我异常的原因而我无法通过互联网找到任何东西,这就是我来到这里的原因.

另外,我给出的反编译代码是由我的IDE使用其导出函数创建的.我想看看null我的构造函数的参数是否是问题,但我不知道如何以不同的方式编译我的代码以反映这一点.如果有人知道我如何更改我得到的导出代码,请通知我.

无论如何,我想知道的是我的代码的哪一部分引起了这个异常,以及我如何解决它.

Nic*_*lai 10

问题来自Java 9模块系统,它强烈地封装了JDK内部API,以及您对JDK内部API的使用,即ObservableListWrapper(您可以告诉它是内部的,因为包名称的开头com.sun).如果您或您的用户通过编译或运行Java 9来使用Java 9,则此错误将持续存在.

正确的解决方法是停止使用ObservableListWrapper.通过判断此演示文稿(PDF) ,你应该使用FXCollections实用工具类来代替.

如果这对您不起作用,则有一种解决方法.添加FXCollections到compile(--add-exports javafx.base/com.sun.javafx.collections=ALL-UNNAMED) launch(javac)命令.


Jac*_* G. 1

事实证明,您正在使用 Java 9 进行编译,它利用了 JDK 的新module系统。可能有一种有效的方法可以通过实现模块来解决您的问题,但是另一种解决方案是简单地使用 Java 8 进行编译!