Understanding Java Class Loaders

Java Class Loaders

You will see here what are the Java class loaders with simple example. Java publicly released in the year of 1995 with a web browser with the ability to automatically and dynamically download applets whenever it encounters <Applet> tag in the HTML document.

Such Applets are loaded on the fly across the network from remote web servers and run inside the browser’s Java Virtual Machine (JVM). The mechanism that enabled such dynamic loading is a class loader.

Class loaders are responsible for determining when and how classes can be added to a running Java environment, as well as making sure that important parts of the Java runtime environment are not replaced by other code.

Application Execution

The process of combining the code into an executable native code is called linking – the merging of separately compiled code with shared library code to create an executable application.

This is different in dynamically compiled programming languages such as Java. In Java, the .class files generated by the Java compiler remain as-is until loaded into the Java Virtual Machine (JVM) — in other words, the linking process is performed by the JVM at runtime. Classes are loaded into the JVM on an ‘as needed’ basis. And when a loaded class depends on another class, then that class is also loaded.

When a Java application is launched, the first class to run (or the entry point into the application) is the one with public static void method called main(). This class usually has references to other classes, and all attempts to load the referenced classes are carried out by the class loader.

Simple Class Example

To get an idea on class loading, I will create a simple class with the following Java code:

public class ClassLoadersApp {
	public static void main(String[] args) {
		System.out.println("Hello, World!");
	}
}

Note that I used JDK 12, Eclipse 4.12 to create the above class.

If you run this class specifying the -verbose:class command-line option (I configured in Eclipse under VM Arguments), so that it prints what classes are being loaded, you will get an output that looks as follows.

I will not show all the class loaders in the output but if you run the above class then you will get all class loaders.

[0.022s][info][class,load] opened: C:\Java\jdk-12.0.2\lib\modules
[0.039s][info][class,load] java.lang.Object source: shared objects file
[0.039s][info][class,load] java.io.Serializable source: shared objects file
[0.040s][info][class,load] java.lang.Comparable source: shared objects file
[0.040s][info][class,load] java.lang.CharSequence source: shared objects file
[0.040s][info][class,load] java.lang.constant.Constable source: shared objects file
[0.040s][info][class,load] java.lang.constant.ConstantDesc source: shared objects file
[0.040s][info][class,load] java.lang.String source: shared objects file
...
[0.040s][info][class,load] java.lang.reflect.Type source: shared objects file
...
[0.070s][info][class,load] java.lang.Boolean source: shared objects file
...
[0.079s][info][class,load] java.util.ImmutableCollections$AbstractImmutableSet source: shared objects file
...
[0.337s][info][class,load] java.lang.PublicMethods$Key source: shared objects file
[0.337s][info][class,load] java.lang.Void source: shared objects file
[0.337s][info][class,load] java.lang.Readable source: shared objects file
[0.338s][info][class,load] java.nio.CharBuffer source: shared objects file
[0.338s][info][class,load] java.nio.HeapCharBuffer source: shared objects file
[0.338s][info][class,load] java.nio.charset.CoderResult source: shared objects file
Hello, World!
[0.338s][info][class,load] jdk.internal.misc.TerminatingThreadLocal$1 source: shared objects file
[0.338s][info][class,load] java.lang.Shutdown source: shared objects file
[0.338s][info][class,load] java.lang.Shutdown$Lock source: shared objects file

As you can see, the Java runtime classes required by the application class  ClassLoadersApp are loaded first.

Understanding Extension Class Loading

When runtime environment needs to load a class in an application, it looks for the class in the following locations in the order as given below:

Bootstrap classes: the runtime classes in rt.jar and internationalization classes in i18nrt.jar and others.

Installed JARs: classes in JAR files in the lib/ext directory of JRE.

Class path: classes including classes in JAR files on path specified by the property java.class.path or simply on classpath.

Understanding Class Loading Mechanism

Java platform has delegation model for loading classes. When loading a class, a class loader finds its parent class loader before attempts to find the class itself because every class loader has a parent class loader.

Some insights of the class-loading API are given below:

  • java.lang.ClassLoader and its subclasses allow to specify the parent class loader while a new class loader gets instantiated. If no such parent class is specified then virtual machine’s system class loader is assigned.
  • The loadClass() method of java.lang.ClassLoader performs the following tasks in order:
    • if class already loaded, return it otherwise delegates the search for new class to the parent class loader.
    • if parent class loader does not find it then loadClass() method calls findClass() method to find and load the class.
  • findClass() method may be overridden when a class loader subclass is instantiated in an application.
  • The class java.net.URLClassLoader serves as the basic class loader for extensions and other JAR files, overriding the findClass() method of java.lang.ClassLoader to search one or more specified URLs for classes and resources.

Class Loaders in Java Platform 2

As of JDK 1.2, a bootstrap class loader that is built into the JVM is responsible for loading the classes of the Java runtime. This class loader only loads classes that are found in the boot classpath, and since these are trusted classes, the validation process is not performed as for untrusted classes.

In addition to the bootstrap class loader, the JVM has an extension class loader responsible for loading classes from standard extension APIs, and a system class loader that loads classes from a general class path as well as your application classes.

Since there is more than one class loader, they are represented in a tree whose root is the bootstrap class loader. Each class loader has a reference to its parent class loader. When a class loader is asked to load a class, it consults its parent class loader before attempting to load the item itself. The parent in turn consults its parent, and so on. So it is only after all the ancestor class loaders cannot find the class that the current class loader gets involved. In other words, a delegation model is used.

You can find more information on class loaders.

Leave a Reply

Your email address will not be published. Required fields are marked *