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,
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());
* @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.SEVERE, null, 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)