Wednesday, 11 November 2015

ClassLoader in Java

Class loaders in Java used to load class. It works on 3 principles -
  1. Delegation - Delegation principle forward request of class loading to parent class loader and only loads the class, if parent is not able to find or load class.
  2. Visibility - It allows child class loader to see all the classes loaded by parent ClassLoader, but parent class loader can not see classes loaded by child.
  3. Uniqueness - Uniqueness principle allows to load a class exactly once, which is basically achieved by delegation and ensures that child ClassLoader doesn't reload the class already loaded by parent.
What is ClassLoader in Java?
ClassLoader in Java is a class which is used to load class files in Java. Java code is compiled into class file by javac compiler and JVM executes Java program, by executing byte codes written in class file. ClassLoader is responsible for loading class files from file system, network or any other source. There are three default class loader used in Java, Bootstrap , Extension and System or Application class loader.

1) Bootstrap ClassLoader - JRE/lib/rt.jar
2) Extension ClassLoader - JRE/lib/ext or any directory denoted by java.ext.dirs
3) Application ClassLoader - CLASSPATH environment variable, -classpath or -cp option, Class-Path attribute of Manifest inside JAR file.


How ClassLoader in Java?
Please refer below diagram - It mainly work on above listed 3 principles -
 
Delegation principles
 When a class is loaded and initialized in Java, a class is loaded in Java, when its needed. Suppose you have an application specific class called Krishna.class, first request of loading this class will come to Application ClassLoader which will delegate to its parent Extension ClassLoader which further delegates to Primordial or Bootstrap class loader. Primordial will look for that class in rt.jar and since that class is not there, request comes to Extension class loader which looks on jre/lib/ext directory and tries to locate this class there, if class is found there than Extension class loader will load that class and Application class loader will never load that class but if its not loaded by extension class-loader than Application class loader loads it from Classpath in Java. Remember Classpath is used to load class files while PATH is used to locate executable like javac or java command.
Visibility Principle
According to visibility principle, Child ClassLoader can see class loaded by Parent ClassLoader but vice-versa is not true. Which mean if class Abc is loaded by Application class loader than trying to load class ABC explicitly using extension ClassLoader will throw either java.lang.ClassNotFoundException. as shown in below Example
Example:
package krishna;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Java program to demonstrate How ClassLoader works in Java,
 * in particular about visibility principle of ClassLoader.
 *
 * @author Krishna Kumar Chourasiya
 */


public class ClassLoaderTestKrishna {
 
    public static void main(String args[]) {
        try {         
            //printing ClassLoader of this class
            System.out.println("ClassLoaderTestKrishna.getClass().getClassLoader() : "

                                 + ClassLoaderTestKrishna.class.getClassLoader());

         
            //trying to explicitly load this class again using Extension class loader
            Class.forName("krishna.ClassLoaderTest", true 

                            ,  ClassLoaderTestKrishna.class.getClassLoader().getParent());
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ClassLoaderTestKrishna.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

Output:
ClassLoaderTestKrishna.getClass().getClassLoader() : sun.misc.Launcher$AppClassLoader@601bb1
11/11/2015 2:43:48 AM krishna.ClassLoaderTestKrishna main
SEVERE: null
java.lang.ClassNotFoundException: krishna.ClassLoaderTestKrishna
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at sun.misc.Launcher$ExtClassLoader.findClass(Launcher.java:229)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:247)
        at test.ClassLoaderTest.main(ClassLoaderTestKrishna.java:29)

Uniqueness Principle
According to this principle a class loaded by Parent should not be loaded by Child ClassLoader again. Though its completely possible to write class loader which violates Delegation and Uniqueness principles and loads class by itself, its not something which is beneficial. You should follow all  class loader principle while writing your own ClassLoader.

No comments:

Post a Comment

Monads in Scala

Monads belongs to Advance Scala   concepts. It  is not a class or a trait; it is a concept. It is an object which covers other object. A Mon...