I have instrumented JDK and application. Entry and exit points are recorded for call graph construction.
The call graph looks like
sun.misc.Launcher$AppClassLoader.loadClass->com.example.Main.main
->sun.misc.Launcher$AppClassLoader.loadClass->com.example.Foo.foo
Source code
public class Main{
public static void main(String[] args){
Foo.foo()
}
}
public class Foo{
public static void foo(){};
}
This must be how classloader works but I don't see anything shows in bytecode that indicate the call site "sun.misc.Launcher$AppClassLoader.loadClass". So, how does classloader work internally?
Classes are loaded lazily.
You can see this by writing code to print to the console within static initialisers.
The first time a class reference is used by any code loaded by a specific class loader, the JVM request the Class
from the loader in the current thread. If the parent class loader hasn't loaded a class of the fully qualified name, then the current class loader will define it (or throw an exception).
In the early days applets would make a network connection for each class file.