what is classloader in java?

ClassLoader in Java is a class that is used to load class files in Java. Java code is compiled into the class file by javac compiler and JVM executes Java program, by executing byte codes written in the class file.

ClassLoader is responsible for loading class files from file system, network or any other source. There are following three default class loader in java:

  • Bootstrap ClassLoader: Loads class from JRE/lib/rt.jar
  • Extension ClassLoader: Loads class from JRE/lib/ext
  • Application ClassLoader: Loads class from CLASSPATH environment variable

ClassLoader in Java

As a part of the Java Runtime Environment, the Java ClassLoader dynamically loads Java classes into the Java Virtual Machine. By the use of classloaders in Java, it is not required to know about files and file systems by the Java run time system. Java classes are loaded when required by an application instead of loading all at once into the memory. The ClassLoader in Java is called by the JRE. These ClassLoaders dynamically loads classes into memory.

Types of ClassLoaders in Java:

All the classes are not loaded by a single ClassLoader. The ClassLoader to load that particular class is decided, depending on the type of class and the path of class. The getClassLoader() method is used to select the ClassLoader that loads a class. The classes are loaded as per their names. A NoClassDefFoundError or ClassNotFoundException is returned if a class is not found. There are three types of Classloader in Java:

Java BootStrap ClassLoader:

Being a Machine code, a Bootstrap Classloader kickstarts the operation when the JVM calls it. It loads the first pure Java ClassLoader but is not a java class. The classes are loaded from the location rt.jar by the Bootstrap ClassLoader. Often called the Primordial ClassLoader, it doesn’t have any parent ClassLoaders.

Java Extension ClassLoader:

The extensions of core java classes are loaded from the respective JDK Extension library by the Extension ClassLoader. It is a child of Bootstrap ClassLoader. The file is loaded by the Extension ClassLoader from the jre/lib/ext directory or any other directory. The directory is pointed by the system property java.ext.dirs.

Java System ClassLoader:

Often known as a System ClassLoader and being a child class of Extension ClassLoader, an Application ClassLoader loads the Application type classes. These classes are found in the environment variable CLASSPATH, -classpath or -cp command-line option.

Order of functioning of the ClassLoader Delegation Hierarchy Model:

The order of the functioning of the ClassLoader Delegation Hierarchy Model is:

Application ClassLoader -> Extension ClassLoader -> Bootstrap ClassLoader

Here, the highest property is given to the Bootstrap ClassLoader, then to Extension ClassLoader and the last priority is given to the Application ClassLoader.

Principles of the functionality of a Java ClassLoader:

The set of rules or features on which a Java ClassLoader works are known as the Principles of functionality. A Java ClassLoader has three principles of functionality. These are:

Delegation Model:

The Delegation Hierarchy Algorithm is an algorithm that is used by the Java Virtual Machine and the Java ClassLoader to Load the classes into the Java file.

The delegation model provides a set of operations based on which the ClassLoader works. These set of operations are given below:

  1. The Delegation Hierarchy Principle is always followed by the ClassLoader.
  2. JVM checks whether a class is already loaded or not when it comes across a class.
  3. JVM proceeds with execution only when the Class is already loaded in the method area.
  4. JVM asks the Java ClassLoader Sub-System to load the specific class, in case the class is not present in the method area. Then the control is handed to the Application ClassLoader by the ClassLoader sub-system.
  5. The request is then delegated to the Extension ClassLoader by the Application ClassLoader. The request is then delegated to the Bootstrap ClassLoader by the Extension ClassLoader.
  6. The Bootstrap ClassLoader searches for the class in the Bootstrap classpath(JDK/JRE/LIB). If present, the class is loaded. The request is delegated to the Extension ClassLoader in case the class is not present.
  7. The class in the Extension Classpath(JDK/JRE/LIB/EXT) is searched by the Extension ClassLoader. It is loaded, in case the class is available. And in case the class is not available, the request is delegated to the Application ClassLoader.
  8. The class in the Application Classpath is searched by the Application ClassLoader. It is loaded, in case the class is available. And in case the class is not available, a ClassNotFoundException exception is generated.

Visibility Principle:

According to the Visibility Principle, a class loaded by a parent ClassLoader is visible to the child ClassLoaders. A class loaded by a child ClassLoader is, however, not visible to the parent ClassLoaders. For example, the EXAMPLE.class is only visible to the Extension ClassLoader and the Application ClassLoader and not to the Bootstrap ClassLoader, if this class is loaded by the Extension ClassLoader. The java.lang.ClassNotFoundException exception will be raised in case the above class is again tried to load using Bootstrap ClassLoader.

Uniqueness Property:

To ensure that all the classes are unique and without any repetition, the Uniqueness Property is utilized. It thus also provides the guarantee that the classes loaded by parent classloaders are not loaded by the child classloaders. The current instance would attempt to find the class, only when the parent class loader isn’t able to find it.

Methods of Java.lang.ClassLoader:

To load a class, the JVM first requests for the class, after which a few more steps are followed. In loading a Class, a vital role is also played by some important Methods or Functions, even though the Classes are loaded as per the delegation model.

loadClass(String name, boolean resolve) method:

To load the classes, referenced by the JVM, the loadClass(String name, boolean resolve) is used. The name of the class is taken as a parameter, by this method. It is of type loadClass(String, boolean).

defineClass() method:

To define an array of bytes as an instance of the class, the defineClass() method is used. Being a final method, cannot be overridden. The ClassFormatError is displayed in case the class is invalid.

findClass(String name) method:

To find a specified class, the findClass(String name) is used. It, however, doesn’t load the class.

findLoadedClass(String name) method:

To verify whether the Class referenced by the JVM was previously loaded or not, the findLoadedClass(String name) is used.

Class.forName(String name, boolean initialize, ClassLoader loader) method:

To load and to initialize a class, the Class.forName(String name, boolean initialize, ClassLoader loader) is used. It also provides a choice to select any one of the ClassLoaders. The Bootstrap ClassLoader is used when the ClassLoader parameter is NULL.

Example:

protected synchronized Class<?> 
loadClass(String name, boolean resolve) 
    throws ClassNotFoundException 
{ 
    Class a = findLoadedClass(name); 
    try { 
        if (a == NULL) { 
            if (parent != NULL) { 
                a = parent.loadClass(name, false); 
            } 
            else { 
                a = findBootstrapClass0(name); 
            } 
        } 
        catch (ClassNotFoundException e) 
        { 
            System.out.println(e); 
        } 
    } 
}

Explanation:

The above code is executed before a class is loaded. It returns it, in case the class has already been loaded. In any other case, the search for the new class is delegated to the parent class loader. To find and load the class, the findClass() method is called by the loadClass(), only when the parent class loader is not able to find the class. In case the class wasn’t found by the parent ClassLoader, the class is searched in the current ClassLoader, by the finalClass() method.