The classlist created using -XX:DumpLoadedClassList option captures the location of the classes loaded by custom classloaders. When generating the archive using this classlist, we create a new URLClassLoader for every unique source in the classlist to load the class. This can create problem if the classes in the hierarchy are loaded from different sources and result in java.lang.IllegalAccessError.
Steps to reproduce:
1. Create a class BaseClass and put in base.jar
2. Create a class SubClass that extends BaseClass and put it in sub.jar
3. Create a main class that uses custom classloader to load classes from base.jar and sub.jar. For example:
import java.nio.file.Path;
import java.nio.file.FileSystems;
import java.net.URL;
import java.net.URLClassLoader;
public class TestApp {
public static void main(String args[]) throws Exception {
Path base = FileSystems.getDefault().getPath("base.jar");
Path sub = FileSystems.getDefault().getPath("sub.jar");
URL[] urls = new URL[] { base.toUri().toURL(), sub.toUri().toURL() };
URLClassLoader cl = new URLClassLoader(urls);
Class<?> cls = cl.loadClass("SubClass");
System.out.println(cls.getName());
}
}
4. Now generate the classlist -XX:DumpLoadedClassList option:
$ java -Xshare:off -XX:DumpLoadedClassList=classlist TestApp
5. Create an archive using the generated classlist:
$ java -Xshare:dump -XX:SharedClassListFile=classlist -XX:SharedArchiveFile=test.jsa -cp base.jar:sub.jar TestApp
This results in the following warning in the output:
java.lang.IllegalAccessError: class SubClass cannot access its superclass BaseClass (SubClass is in unnamed module of loader java.net.URLClassLoader @19dfb72a; BaseClass is in unnamed module of loader java.net.URLClassLoader @7f63425a)
and the SubClass does not get added to the generated archive.
In this case the warning does not prevent us from generating the archive, but if there is an entry in the classlist for a class SubClass2 derived from SubClass, then the classlist processing terminates with an error:
An error has occurred while processing class list file classlist 724:29.
Super class id 699 is not yet loaded:
SubClass2 id: 700 super: 699 source: /tmp/cdstest/sub.jar
^
Error occurred during initialization of VM class list format error.
Steps to reproduce:
1. Create a class BaseClass and put in base.jar
2. Create a class SubClass that extends BaseClass and put it in sub.jar
3. Create a main class that uses custom classloader to load classes from base.jar and sub.jar. For example:
import java.nio.file.Path;
import java.nio.file.FileSystems;
import java.net.URL;
import java.net.URLClassLoader;
public class TestApp {
public static void main(String args[]) throws Exception {
Path base = FileSystems.getDefault().getPath("base.jar");
Path sub = FileSystems.getDefault().getPath("sub.jar");
URL[] urls = new URL[] { base.toUri().toURL(), sub.toUri().toURL() };
URLClassLoader cl = new URLClassLoader(urls);
Class<?> cls = cl.loadClass("SubClass");
System.out.println(cls.getName());
}
}
4. Now generate the classlist -XX:DumpLoadedClassList option:
$ java -Xshare:off -XX:DumpLoadedClassList=classlist TestApp
5. Create an archive using the generated classlist:
$ java -Xshare:dump -XX:SharedClassListFile=classlist -XX:SharedArchiveFile=test.jsa -cp base.jar:sub.jar TestApp
This results in the following warning in the output:
java.lang.IllegalAccessError: class SubClass cannot access its superclass BaseClass (SubClass is in unnamed module of loader java.net.URLClassLoader @19dfb72a; BaseClass is in unnamed module of loader java.net.URLClassLoader @7f63425a)
and the SubClass does not get added to the generated archive.
In this case the warning does not prevent us from generating the archive, but if there is an entry in the classlist for a class SubClass2 derived from SubClass, then the classlist processing terminates with an error:
An error has occurred while processing class list file classlist 724:29.
Super class id 699 is not yet loaded:
SubClass2 id: 700 super: 699 source: /tmp/cdstest/sub.jar
^
Error occurred during initialization of VM class list format error.
- relates to
-
JDK-8354315 AOT cache should support only boot classes with -Djava.system.class.loader
-
- Open
-
- links to
-
Review(master) openjdk/jdk/24223