Oct 25, 2014

Textual description of firstImageUrl

What is class loading in java - Internals of class loading in java

Lets start our discussion with fundamental question which was asked to me in Oracle Interview: What happens when we run a class file with main method in Java run environment(JRE) with command java <class_file_name> ags1 ,args2 ? OR What happens when we run a java application from command line ?
Answer: First an instance of java virual machine(JVM) is created, and binary representation of a class file is loded in JVM. After that Java Virtual Machine(JVM) links the initial class(class_file_name),initializes it, and invokes the public class method void main(String[]).The invocation of this method drives all further execution. Class loading is crucial step for successful execution of java application.
The main agenda of this post is to understand internals of java class loading.

What is class loader ?

Class loader is a java program(except primordial class loader, we will visit it later) which is responsible for loading class files from file system, network and other resources(i.e rt.jar from JDK).Before going into detail of class loader, we need to understand two important concept which is prerequisite to understand class loading mechanism.

1.What is importance of  "java.lang.Class" in java?
Instances of the class Class represent classes and interfaces in a running Java application. It means, whenever a java file is compiled, the compiler will insert a public, static, final field named class, of the type java.lang.Class into generated .class file, so each and every class exposes its code in the form of an instance of java.lang.Class. Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader. Since this field is public it is accessible from any where and it can be accessed like this :
  //accessing getName() method via class field.
  System.out.println("The name of class Foo is: "+
                             Foo.class.getName());

2. How fully qualified name(FQN) is different at package level(with reference to package) and JVM level?

In Java, a class is identified by its fully qualified class name(i.e : java.lang.Object. java.util.HashMap,etc). The fully qualified class name consists of the package name and the class name. However, at JVM level a class is uniquely identified using its fully qualified class name along with the instance of the Class loader that loaded that particular class.
Lets understand above discussion with an example: if a class named "Classl" in the package "Package" is loaded by an instance "clsLoader1" of the class loader "ClassLoader", the class instance of Class1, i.e. Class1.class is keyed in the JVM as [Classl, Package, ClassLoader].Similarly, if we have an another instance in JVM as [Class1, Package, ClassLoader2],This means that the two class loader instances [Classl, Package, ClassLoader] and [Class1, Package, ClassLoader2] are not same, and classes loaded by them are also completely different. So, important take away from this discussion is : In JVM every class is loaded in context of class loader.

Now come back to our class loading discussion, In Java, class loader follows class hierarchy (parent/child class loader relationship) and works on the principle of Delegation and Visibility. Delegation principle states that :Every class loader(child) before loading any class forward request to its parent class, if parent class does not load requested class ,then only child class will load it.In this way delegation ensures that child Class loader doesn't reload the class already loaded by parent. Visibility principle states that class loaded by parent class is visible to child class loader but parent class loader can not see classes loaded by child.
There are three default class loader used in Java: 1.Bootstrap  2.Extension 3.System or Application class loader. All these class loaders has a predefined location, from where they loads class files.
As we saw earlier, in java each class is loaded by its class loader, and each class loader itself is a class and must be loaded by another class loader, we seem to have the obvious chicken-and-egg problem, i.e.,  From where the very first class loader come from? It is Bootstrap class loader which kick-off class loading.
Bootstrap Class loader: It is responsible for loading standard JDK class files from JRE\lib\rt.jar(java.lang.Object and other runtime class) and i18.jar used for internationalization.It is parent of all class loaders in Java and it does not have any parents.It is also called "primordial class loader' and it written in a native language, such as C, and does not manifest itself within the Java context.For the same reason, the behavior of the bootstrap class loader will also differ across JVMs.
Question :Why System.out.println(java.lang.String.class.getClassLoader()) display null ?
Answer: Since java.lang.String belong to rt.jar and it is loaded by Bootstrap class loader(native implementaion).That's why, it does return null(not any valid class name).

Extension Class loader:
It is responsible for loading all .jar files from "jre/lib/ext" or any other directory pointed by java.ext.dirs system property.Please note,it first forward request to its parent class(Bootstrap) to do loading, if unsuccessful, it loads. Extension Class loader in JVM is implemented by sun.misc.Launcher$ExtClassLoader.

System class loader or AppClassLoader:
It is responsible for loading application specific classes from CLASSPATH environment variables(or Class-Path attribute of Manifest file inside JAR).Extension class loader is immediate parent of Application class loader and its implemented by sun.misc.Launcher$AppClassLoader class.
Note: All Java class loaders extend java.lang.ClassLoader except Bootstrap class loader.

We can summarize above discussion with an example.Consider the following sample code which initialize(try to create an instance of String class) and refer below diagram. Lets explain the flow how CustomClass and String class is loaded ?

The directory location of CustomClass is configured in CLASSPATH environment variable so,CustomClass is loaded by System class loader and is visible to it.When System class loader receives a request to load String class then it forward request to parent class Ext. class loader and Ext.class loader forward this request to Bootstrap class loader.String class is already available, since it is part of rt.jar and loaded by Bootstrap loader. Since String class loaded by parent class loader it is visible to Ext. class loader and system class loader.It was all about default class loader.

Question : What are the method calls performed internally while class loading in java ?
Answer : When JVM requests for a class, it invokes loadClass(<class_name>) function of the ClassLoader by passing the fully classified name of the Class and in turn loadClass function calls for findLoadedClass() method to check that the class has been already loaded or not. It’s required to avoid loading the class multiple times and uniqueness is maintained. If the Class is not already loaded then it will delegate the request to parent ClassLoader to load the class. If the parent ClassLoader is not finding the Class then it will invoke findClass() method to look for the classes in the file system and load it, if found else it will throw ClassNotFound exception.

Apart from default class loader, by extending ClassLoader we can write our own custom class loader.
Question : Why do we need custom class loader and where do we use it ?
Answer :  Java default class loader can load files from local file system that is good enough to full-fill  most of the requirement.However, if we need to load a class from different network via FTP or load resources dynamically at run-time, etc. For such case we need our own custom class loader.Other situation when we need can be found here.
                             ==========End of article============

Happy learning,
Nikhil

Location: Hyderabad, Telangana, India