Pages

How Java Class is loaded into JVM


How Java Class is loaded into JVM


Java ClassLoader loads the classes at runtime. Class Loader in java works on three principle: Delegation, Visibility and Uniqueness .

1. Delegation: Delegation forward the incoming request of a class loading to a parent ClassLoader and only loads the class.

2. Visibility : Visibility allows child ClassLoader to see or check whether all classes is loaded by the parent ClassLoader but parent  ClassLoader can not check whether all classes loaded by the child ClassLoader.

3. Uniqueness: uniqueness allows to load a class exactly once. Which is basically achieved by the delegation and ensure that child ClassLoader doesn’t reload the class already loaded by the parent.

Note : One java class couldn’t loaded by two different ClassLoader.

ClassLoader in Java is a class which is used to load the class files in java. Java code is complied using javac complier and JVM executes the java program by running the byte code from the class file. ClassLoader is responsible to load the class from the file system, network or any other sources.

There are three type of ClassLoader in java and every ClassLoader has predefined location from where they loads the classes. 

      1.  BootStrap ClassLoader  Or Primordial 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, -cp option, ClassPath attribute                             in Manifest inside a JAR)







BootStrap ClassLoader is parent of all the ClassLoader in java, If you call String.class.getClassLoader() it will return null. Extension ClassLoader delegates request to parent ClassLoader (Bootstrap), If it fails to find the class than Extension ClassLoader loads the class from JRE/lib/ext or JRE/ext/dirs (System Property). Extension ClassLoader in JVM is implemented by sun.misc.Launcher$ExtClassLoader

Third default ClassLoader  used by JVM is System or Application ClassLoader. It loads the classes from classpath, -cp command line option, Class-Path attribute of Manifest file inside JAR
Application ClassLoader is the child of Extension ClassLoader and implemented by sun.misc.Launcher$AppClassLoader class. Bootstrap ClassLoader is basically implemented in native language like C. All java class loaders are implemented  using java.lang.ClassLoader.






Delegation Principles : A class is loaded in java when it needs or requires. Suppose you have an application specific class called Employee.class, first request of loading this class will come to Application ClassLoader which will delegates request to Extension ClassLoader which further delegates it to Bootstrap ClassLoader. Bootstrap or Primordial ClassLoader will check this class in JRE/lib/rt.jar and since this class is not there, request comes to Extension ClassLoader which looks this class in JRE/lib/ext or JRE/ext/dirs directory and tries to locate this class there. If class is found there than Extension ClassLoader will load that class and Application ClassLoader will never load this class But if its not loaded by Extension ClassLoader than Application ClassLoader load this class from classpath in java.

Note: classpath is used to load  class files while PATH is used to executable like javac or java command.

Visibility Prinicples : Child ClassLoader can see or check classes loaded by parent ClassLoader but it’s vice versa not true. Which mean if Employee class is loaded by Application ClassLoader than trying to load this class explicly using Extension ClassLoader will throw java.lang.ClassNotFoundException.

Uniqueness Principles : 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.


How to load class explicitly in java :

Java provides API to explicitly load a class by Class.forName(classname) and Class.forName(classname, initialized, classloader),  As shown in below example you can pass name of ClassLoader which should be used to load that particular class along with binary name of class. Class is loaded by calling loadClass() method of java.lang.ClassLoader class which calls findClass() method to locate bytecodes for corresponding class. In this example Extension ClassLoader uses java.net.URLClassLoader which search for class files and resources in JAR and directories. any search path which is ended using "/" is considered directory. If findClass() does not found the class than it throws java.lang.ClassNotFoundException and if it finds it calls defineClass() to convert bytecodes into a .class instance which is returned to the caller.


Where to use ClassLoader in Java :

ClassLoader in Java is a powerful concept and used at many places. One of the popular example of ClassLoader is AppletClassLoader which is used to load class by Applet, since Applets are mostly loaded from internet rather than local file system, By using separate ClassLoader you can also loads same class from multiple sources and they will be treated as different class in JVM. J2EE uses multiple class loaders to load class from different location like classes from WAR file will be loaded by Web-app ClassLoader while classes bundled in EJB-JAR is loaded by another class loader. Some web server also supports hot deploy functionality which is implemented using ClassLoader. You can also use ClassLoader to load classes from database or any other persistent store.

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

/**
 * Java program that define How ClassLoader works in Java,
 * in particular about visibility principle of ClassLoader.
 *
 * @author Anuj Verma
 */


public class ClassLoaderTest 
{

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


       
            
//trying to explicitly load this class again using Extension class loader
            Class.
forName("test.ClassLoaderTest"true 
                            ,  ClassLoaderTest.class.getClassLoader().getParent());

        
} catch (ClassNotFoundException ex) {
            Logger.
getLogger(ClassLoaderTest.class.getName()).log(Level.SEVEREnull, ex);
        
}
    
}

}

Output:
ClassLoaderTest.
getClass().getClassLoader() : sun.misc.Launcher$AppClassLoader@601bb1
16/08/2012 2:43:48 AM test.ClassLoaderTest
 main
SEVERE: 
null
java.
lang.ClassNotFoundException: test.ClassLoaderTest
        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(ClassLoaderTest.java:29)