What loads the java system classloader?

Solution 1:

Bootstrap classloader is the parent of all classloaders and loads the standard JDK classes in lib directory of JRE (rt.jar and i18n.jar). All the java.* classes are loaded by this classloader.

Extensions Classloader is the immediate child of Bootstrap classloader. This classloader loads the classes in lib\ext directory of the JRE.

System-Classpath classloader is the immediate child of Extensions classloader. It loads the classes and jars specified by the CLASSPATH environment variable

You could try to inject your custom class loader by means of the "java.system.class.loader" property (see ClassLoader#getSystemClassLoader).

Default System class loader is parent for MyClassLoader instances,

Solution 2:

From the Javadoc for ClassLoader.getSystemClassLoader:

If the system property "java.system.class.loader" is defined when this method is first invoked then the value of that property is taken to be the name of a class that will be returned as the system class loader. The class is loaded using the default system class loader and must define a public constructor that takes a single parameter of type ClassLoader which is used as the delegation parent.

The default system class loader itself is specific to the JVM implementation.

Solution 3:

Tldr:

§ ..the value of that property is taken to be the name of a class that will be returned as the system class loader. The class is loaded using the default system class loader..

..Thus, if your classloader replaces X as the system class loader, then your classloader's parent will be X, the default system class loader.

(X is of a type like sun.misc.Launcher$AppClassLoader.)

More info can be found at docs.oracle.com - How the Java Launcher Finds Classes:

The Java launcher, java, initiates the Java virtual machine. The virtual machine searches for and loads classes in this order:

Bootstrap classes - Classes that comprise the Java platform, including the classes in rt.jar and several other important jar files.

Extension classes - Classes that use the Java Extension mechanism. These are bundled as .jar files located in the extensions directory.

User classes - Classes defined by developers and third parties that do not take advantage of the extension mechanism. You identify the location of these classes using the -classpath option on the command lineor by using the CLASSPATH environment variable.

Tsmr:

We can prove that X is really the parent of our Classloader:

/** run with -Djava.system.class.loader=MyCL to use this classloader */
public class MyCL extends ClassLoader {
    public MyCL(ClassLoader parent) { // this constructor must be public, else IllegalAccessException
        super(parent);
    }
}

This is our main code:

public class Main {
    public static void main(String args[]) {
        System.out.println("getSystemClassLoader(): " + ClassLoader.getSystemClassLoader());

        ClassLoader cl = MyCL.class.getClassLoader();
        System.out.println("Classloader of MyCL: " + cl);

        Class type_of_cl = cl.getClass();
        System.out.println("..and its type: " + type_of_cl);

        ClassLoader cl_of_cl = class_of_cl.getClassLoader();
        System.out.println("Classloader of (Classloader of MyCL): " + cl_of_cl);
    }
}

This is the output (on my system) when run using the command java -Djava.system.class.loader=MyCL Main (cf. Eclipse run config):

getSystemClassLoader(): MyCL@1888759
Classloader of MyCL: sun.misc.Launcher$AppClassLoader@7fdcde
..and its type: class sun.misc.Launcher$AppClassLoader
Classloader of (Classloader of MyCL): null

We can see that MyCL's classloader is sun.misc.Launcher$AppClassLoader, which is the default system classloader.

(Per the language as seen in Oracle's other quote above, the default system classloader is also called the classloader of "User Classes". Screw Oracle for coming up with 2 names for the same thing.)