I've been working on a little project of my own in Java, and recently, I compiled it and received this error:
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
So, I currently have three different classes, all in the same package. My hierarchy is as follows:
• Kröw
• DataManager
♦ ConstructList
In previous versions of my program, my hierarchy was like this:
• Kröw
♦ DataManager
- ConstructList
In both cases, ConstructList
extended com.sun.javafx.collections.ObservableListWrapper<Construct>
. (I don't think that the class Construct
is necessary here and I'd rather not show it, but I can if needed.)
Anyways, right now, my IDE can run the application as expected, however, when I export it, the above exception is given to me.
Full Stack Trace:
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)
Part of class Kröw
that is mentioned in the error:
private static final DataManager DATA_MANAGER = DataManager.getDataManager(); // line 23
Parts of class DataManager
that are mentioned in the error:
static DataManager getDataManager() { // line 66
return new DataManager();
}
and
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() {
...
}
}
Now, I have looked at the resources that I could find, such as IllegalAccessError SO Question
(Notice how this said: "tried to access method" instead of "superclass access check failed")
The accepted answer to that solution was to check if anything is different between the compiled jar file and my source code, so I tried that and found some minor differences. Here are the changed lines of code from my decompiled jar file. (Decompiled using JD-GUI)
Class DataManager
:
public final ConstructList constructs = new ConstructList(null);
Used to be:
public final ConstructList constructs = new ConstructList();
Class ConstructList
:
private ConstructList() {
super();
}
Used to be:
private ConstructList() {
super(new ArrayList<>());
}
Now, in the decompiled code, the ConstructList()
constructor does not have any parameters, and I see it being invoked with null
being passed in, which looks like an error to me, but I'm not sure if it is the cause of my exception and I haven't been able to find anything via the internet, which is why I came here.
On another note, the decompiled code I've given was created by my IDE, using its export function. I would like to see if the null
argument with my constructor is the problem, but I do not know how to compile my code in a different way to reflect that. If someone knows how I can change the exported code I am getting, please inform me.
Anyways, what I want to know is what part of my code this exception is caused by, and how I can fix it.
The problem arises from the Java 9 module system, which strongly encapsulates JDK-internal APIs, and your use of JDK-internal API, namely ObservableListWrapper
(you can tell it's internal because the package name starts with com.sun
). This error will persist if you or your users use Java 9 either by compiling or running on it.
The proper fix is to stop using ObservableListWrapper
. Judging by this presentation (PDF), you should be using the FXCollections
utility class (update: FXCollections
in OpenJFX 11) instead.
If that doesn't work for you, there is a workaround. Add --add-exports javafx.base/com.sun.javafx.collections=ALL-UNNAMED
to the compile (javac
) and launch (java
) command.
JavaFX is a set of modules in JDK 9, the javadoc is here: http://download.java.net/java/jdk9/jfxdocs/overview-summary.html
The javafx.base module is the base APIs and if you look at the packages listed in the javadoc then you won't see com.sun.javafx.collections. This is because that package is internal (not-exported) to the javafx.base module. Nothing outside of JavaFX should be using it. You can of course use command line options to workaround this but I think you have to look at the usage to understand why it's trying to use a JavaFX internal class. Once the dependency on the internal class is removed then I assume the application should work as before.
It turns out you were compiling with Java 9 which utilizes the JDK's new module
system. There is probably a valid way to fix your problem by implementing modules, however another solution is to simply compile with Java 8!
I think you answered your own question. The error will be probably gone if you update your jar containing the minor differences.
IllegalAccessorError: superclass access check failed
... another solution is to simply compile with Java 8!
I was able to avoid this by switching my Java 11 compiler to Code Level 8 and moving public static void main(String[] args ...)
to a non-FX class and constructing my JavaFX Application
) there instead.
Should this work? Is this a bug? I'm compiling with AdoptOpenJDK 11, but using Language Level 8. Without this workaround, the exception is throwing for me inside IntelliJ, so if Language Level 8 should naturally suppress it, it may simply be a nuance of the IDE.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With