An Introduction to Java Class Loaders

One of the main features of Java is "Write Once and Run Anywhere". The
Java Virtual Machine (JVM) is responsible for loading and executing the code. For this purpose, it uses the java class loader. The java class loaders are responsible for loading appropriate classes in the JVM at the runtime. In a JVM, each and every class is loaded by some instance of a
java.lang.ClassLoader. The main feature of the classloader is that JVM
doesn’t need to have any knowledge about the classes that will be loaded at runtime. ClassLoaders support features like hot deployment and runtime platform extensibility. The next section explains how a class loader works.

Classloader functioning

A class file is the smallest unit that gets loaded by the class loader. It contains binary representation of a java class
and contains bytecodes and links to other class files that will be used. Class loader reads this bytecode and creates the instance of
java.lang.Class. When the JVM starts, initially only the class file is loaded and other classes are loaded as and when required by the JVM. In this process, JVM is initially
unaware of what classes will be loaded later on. Lazy loading plays a key role in providing dynamic extensibility to the Java platform.
In lazy loading, dependents are only loaded as they are specifically
requested.

Different class loaders are responsible for loading different classes from different repositories.

  1. First the " bootstrap class " loader loads the key classes
  2. Next comes the " java extension class "loader. It loads the libraries, which are not part of the core java run time.
  3. The ExtClassLoader is responsible for loading all .jar files kept in the java.ext.dirs path.
  4. Finally, the developer can add his own custom classes needed by the application.

Figure 1 below explains hierarchy of different class loaders.

Java ClassLoader Hierarchy

Figure 1: Hierarchy of class loaders

The process of loading of a class by a class loader is not standalone process. Its a 3-step process.

  1. Loading
  2. Linking
  3. Initialization

Loading is the process of locating the binary representation of a type and bringing it into the JVM. Linking is the process of taking the type and incorporating it into the runtime state of the JVM so that it can be executed. Initialization is the process of executing the initializers of a type (static initializers for classes; static field initializers for classes and interfaces). Once a class becomes unreachable it is available for garbage collection.

The next section deals with how the requested class is searched and loaded by a class loader

How does a Class Loader work?

When a client requests to load a particular class, a check is performed by the class loader to see whether the requested class is already loaded. If the class is already loaded then loaded class is returned and
the request ceases. However if the class is not loaded, then the request is sent to the parent class loader to search for the requested class. This request for search can go upto
the level of bootstrap loader (highest in the hierarchy). If the parent is
successful in finding the class then that class is returned and the
request ceases, but if that does not work out, then the current class
loader has to find the requested class.

Each class loader has a specific location for searching the class. e.g.
bootstrap loader searches for folders, zips and jars. The methods that are
invoked to search for and load the requested class are

  1. protected Class findClass (String className) throws ClassNotFoundException
  2. public class loadClass (String className) throws ClassNotFoundException

Security Issues

With the power of loading any class at runtime, comes the problem of security. For e.g. suppose you load a custom class from your class repository named "java.lang.myclass ". Such a class
doesn’t exist in java.lang package, but at the same time there is a risk of " myclass " class accessing crucial variables of any class of
java.lang package.
A simple class loader code to check the namespace (for the above problem):

if (className.startsWith("java.")) throw newClassNotFoundException();

It?s the responsibility of class loader to protect the namespace. To ensure this JVM now imposes loading constraints. A loading constraint indicates that a name in one namespace MUST refer to the same type data in the method area as the same name in another namespace. A JVM at any moment of time can add new constraints. If any of the constraints are violated, a " LinkageError "will be thrown.

Another issue is that before searching the requested class, the class loader should verify the integrity of the class name. For e.g. if a relative path is specified to a class loader it should be able to understand the path.. So it should check the integrity first and then search for the specified class.

The next example shows the sequence in which different classloaders load the requested classes.

Example

package p1;
public class Myclass1{
    public int i =3;
    public Myclass1(){
           System.out.println(" base constructor");
           System.out.println("n =" +i);
    }
}

package p2;
import p1.Myclass1;
import java.util.*;
public class Myclass2{
    public static void main(String args[]) {
        Myclass1 m = new Myclass1();
        System.out.println("value of n from package p1 n="+m.i);
        Date d1=new java.util.Date();
        System.out.println("Current date = "+d1);
    }
}

Consider the above two packages. In package p2 , two packages are imported

  • package p1
  • java.util

When package p2 is executed in the JVM, first the bootstrap loader will load the basic class files those are needed for execution. Next the
ExtClassLoader loader will load the libraries, which are beyond (or not available) with the core JVM package.
In the above e.g. the java.util.date is not the part of core JVM package, hence it needs to be loaded by the class loader, It will be loaded after the key classes are loaded by the bootstrap loader.
Finally as shown in the above program when

System.out.println(?value of n from package p1 n=?+n); line is executed then the application class loader loads package p1. It?s a custom package and will be loaded when the request for that class is made.

Conclusion

Thus class loaders offer a very powerful mechanism by which classes can be loaded at runtime. Its power lies in its extensibility, i.e. custom classes needed for the application can be loaded in addition to the basic classes loaded by bootstrap loader. But with such powerful tool comes some security problems
as well. Its important for application developers to understand the functioning of classloaders to make their application efficient and and it will also make debugging easy.

The following two tabs change content below.
Content Team

Content Team

The IndicThreads Content Team posts news about the latest and greatest in software development as well as content from IndicThreads' conferences and events. Track us social media @IndicThreads. Stay tuned!
Content Team

Content Team

The IndicThreads Content Team posts news about the latest and greatest in software development as well as content from IndicThreads' conferences and events. Track us social media @IndicThreads. Stay tuned!

  • Noname

    I never want to have to write networking code with any other language again!

  • Noname

    How the class is instanciated without loading the class…….. can anybody tell me, or what i am interpreating is wrong…… Ashish Pande. ashishpande18@gmail.com

  • Guest

    Good article….

    I think you should add a little comment/warning about the Classloader when running inside a J2EE Application Server, the behavior is a little different and more complex

  • karthikg

    As indicated in the earlier post, java.util.date will be loaded by the bootstrap classloader. It is present in rt.jar

    Ajith ,
    what you say is correct.

  • ajith

    HI,
    My understanding is that the Extension class loader loads classes with javax…… package structure and also the jar files in the ext directory of the JDK ie JAVA_HOME/jre/lib/ext dir
    IS this correct?

    ~Ajith KR

  • Guest

    The last section seems incorrect / incorrectly phrased to me.

    [quote]
    In the above e.g. the java.util.date is not the part of core JVM package, hence it needs to be loaded by the class loader, It will be loaded after the key classes are loaded by the bootstrap loader
    [/quote]

    A class that ships with standard jdk will be loaded by the bootstrap classloader.

  • Guest

    ‘Write Once and Test Anywhere’ is true

  • add

    Thats the thing, when the statement
    Myclass1 m = new Myclass1(); gets executed
    the class loader will load the package p1 automatically at run time .
    Thats the work of class loader. Icould have writen import p1 but I specifically need myclass1.

  • Guest

    Sorry, why the package p1 is not loaded when instantiating class Myclass1? that is when the line:
    Myclass1 m = new Myclass1(); ???

  • Guest

    That enriches my knowledge!!
    Informative concise and well written.