Class creation in JVM specification vs Hotspot behavior
Pietro Braione
pietro.braione at unimib.it
Sat Nov 26 10:00:40 UTC 2022
Hello to all the JVMS and Hotspot experts; I hope you can help me clarifying an issue. Section 5.3.2 of the JVMS discusses the class creation/loading procedure for classes with an user-defined class loader, but what it says seems to disagree with what Hotspot actually does. Section 5.3.2, third paragraph, says that when L is a user-defined class loader and L must create a class with name N, first, the method L.loadClass(N) is invoked, that actually loads and creates a class C, and then L is registered as an initiating loader for C. But apparently Hotspot does not register L as an initiating loader, at least from what appears by debugging this code snippet (I have the same results with Temurin OpenJDK 8 and OpenJDK 17):
package example;
class Foo { }
class Test {
public static void main(String[] args) {
ClassLoader L = new ClassLoader() { }; //1
L.loadClass(“example.Foo”); //2
L.loadClass(“example.Foo”); //3
}
}
After statement 2 L is the initiating loader of a class C with name Foo, and the application class loader is the defining loader for C. When statement 3 is executed, the method ClassLoader.loadClass(String, boolean) is invoked, whose first step is invoking the method ClassLoader.findLoadedClass(String) to determine whether the class is already loaded. The Javadoc of this method states:
"Returns the class with the given binary name if this loader has been recorded by the Java virtual machine as an initiating loader of a class with that binary name. Otherwise null is returned.”
So, being L an initiating loader for C, the invocation of L.findLoadedClass(“Foo”) should return C. Instead, it returns null. So I am lead to conclude that of the three, one: either the behavior of ClassLoader.findLoadedClass(String) disagrees with its Javadoc documentation, and the method does *not* return all the classes for which the classloader is an initiating loader; or Hotspot fails in registering L as an initiating loader of C - which would be bad since it would also mean that Hotspot fails to check a loading constraint (Section 5.3); or there is a mistake in the JVMS, section 5.3.2 and L should not be registered as an initiating loader for C.
Am I missing something?
Cheers
Pietro Braione
University of Milano-Bicocca
More information about the jls-jvms-spec-comments
mailing list