Can the Java System class Loader really be replaced?
Java has a property named -Djava.system.class.loader
for replacing the system class loader.
However, any class created using new, rather than .newInstance()
shows AppClassLoader
as its class loader.
AppClassLoader
is also known as the system class loader, so it doesn't seem that any real replacing is going on.
For example, when running (Oracle Hotspot on Windows JDK 1.8)
// Run with java -Djava.system.class.loader=classLoaders.MyClassLoader Example
public class MyClassLoader extends ClassLoader {
public MyClassLoader(ClassLoader parent) {
super(parent);
}
@Override
public Class loadClass(String name) throws ClassNotFoundException {
System.out.println("Loading class :" + name);
return super.loadClass(name);
}
}
class A {
}
public class Example {
public static void main(String[] args) throws Exception {
System.out.println(ClassLoader.getSystemClassLoader());
System.out.println(new Example().getClass().getClassLoader());
System.out.println(new A().getClass().getClassLoader());
}
}
The output is:
Loading class :classLoaders.Example
classLoaders.MyClassLoader@6d06d69c
sun.misc.Launcher$AppClassLoader@58644d46
sun.misc.Launcher$AppClassLoader@58644d46
While the first instance of Example
is being loaded by MyClassLoader
, and the method getSystemClassLoader
returns the MyClassLoader
, any class created using new is loaded by the original System Class Loader, so what exactly is being replaced?