Friday, September 13, 2013

Concepts of Class Loader in Java

In this post we'll dig into working of java class loading concept, how class are loaded, how classloader works types of classloader, and so on. I'm trying my best to give classloader detail in a easiest way. I hope you gonna like it.

What is JVM?
JVM is a virtual machine that can execute Java bytecode. It's the code execution component of the java platform.
What is ClassLoader?
The Java Classloader is a part of the Java Runtime Environment that dynamically loads Java classes into the Java Virtual Machine.

The Java run time system does not need to know about files and file systems because of classloader.




Delegation is an important concept to understand when learning about classloaders. Delegation refers to the feature used in programming language making use of method lookup.












In terms of Java, A class loader is an object that is responsible for loading classes. The class ClassLoader is an abstract class. Given the binary name of a class, a class loader should attempt to locate or generate data that constitutes a definition for the class. A typical strategy is to transform the name into a file name and then read a "class file" of that name from a file system.
Every Class object contains a reference to the ClassLoader that defined it.


Before going into detail let's see what types of classloader are used when JVM start.

There are 3 types of classloader 


  1. Bootstrap class loader
  2. Extensions class loader
  3. System class loader or AppClassLoader






The bootstrap class loader : responsible for loading key Java classes like java.lang.Object and other runtime code into memory first and loads the core Java libraries located in the <JAVA_HOME>/jre/lib directory. This class loader, which is part of the core JVM, is written in native code.

The extensions class loader : loads the .jar files in the extensions directories <JAVA_HOME>/jre/lib/ext, or any other directory specified by the java.ext.dirs system property.

The System class loader or AppClassLoaderThe third and most important class loader from the developer perspective is the AppClassLoader. The application class loader is responsible for loading all of the classes kept in the path corresponding to the java.class.path system property.


When and how ClassLoader comes into picture
One thing to note is that each and every class is loaded by some instance of a java.lang.ClassLoader. It is located in java.lang package and we are free to subclass it to add more functionality to class loading.

Whenever we type "java myclass", the bootstrap loader is responsible for loading key Java classes like java.lang.Object and other runtime code into memory first.The runtime classes are packaged inside of the JRE\lib\rt.jar file. It's implementation is native so we can't find bootstrap class loader in the Java documentation.

Next comes the Java extension class loader. We can store extension libraries providing features that goes beyond the java code runtime code in the path given by the java.ext.dirs property.The ExtClassLoader is responsible for loading all .jar files kept in the java.ext.dirs path.
T
he third and most important class loader from the developer perspective is the AppClassLoader. The application class loader is responsible for loading all of the classes kept in the path corresponding to the java.class.path system property.

In the java tool, the -classpath option is a shorthand way to set the java.class.path property. The -cp and -classpath options are equivalent.
There are few other class loaders in the JDK:
  • java.net.URLClassLoader
  • java.security.SecureClassLoader
  • java.rmi.server.RMIClassLoader
  • sun.applet.AppletClassLoader
**interview question
How thread related to class loader
java.lang.Thread, contains the method public ClassLoader getContextClassLoader(), which returns the context class loader for a particular thread. The context class loader is provided by the creator of the thread for use by code running in this thread when loading classes and resources. If it is not set, the default is the class loader context of the parent thread.

**interview questionWhen classes are loaded in java?
  1. A new instance of Class X is created
    new statement
    Reflection
    Cloning
    Deserialization
  2. When a static method of X is invoked
  3. When a static field of X is read or written
  4. When a method in java.lang.Class or java.lang.reflect.* needs information about X
  5. When a subclass of X is initialized

The Java Class Loading Mechanism

The Java platform uses a delegation model for loading classes. The basic idea is that every class loader has a "parent" class loader. When loading a class, a class loader first "delegates" the search for the class to its parent class loader before attempting to find the class itself.


  1. Constructors in java.lang.ClassLoader and its subclasses allow you to specify a parent when you instantiate a new class loader. If you don't explicitly specify a parent, the virtual machine's system class loader will be assigned as the default parent.
  2. The loadClass method in ClassLoader performs these tasks, in order, when called to load a class:
    * If a class has already been loaded, it returns it.
    * Otherwise, it delegates the search for the new class to the parent class loader.
    * If the parent class loader does not find the class, loadClass calls the method findClass to find and load the class.
  3. The findClass method of ClassLoader searches for the class in the current class loader if the class wasn't found by the parent class loader. You will probably want to override this method when you instantiate a class loader subclass in your application.
  4. The class java.net.URLClassLoader serves as the basic class loader for extensions and other JAR files, overriding the findClass method of java.lang.ClassLoader to search one or more specified URLs for classes and resources.



We'll see this mechanism in terms of code also in the following section " How class loader works".



How class loader differentiate between the classes?
Once a class is loaded into a JVM, the same class (I repeat, the same class) will not be loaded again. 
We'll see how jvm identify that class is already loaded or not.
In java, a class is identified by its fully qualified class name. The fully qualified class name consists of the package name and the class name.
But a class is uniquely identified in a JVM using its fully qualified class name along with the instance of the ClassLoader that loaded the class

For instance, if a class named C1 in the package pkg1 is loaded by an instance claLoad1 of the class loader, the class instance c1 i.e, c1.class is key in the JVM as (C1,pkg1,claLoad1).
This means that the two class loader instances (C1, pkg1, claLoad1) and (C2, pkg2, claLoad2) are not one and the same, and classes loaded by them are also completely different and not type-compatible to each other. 


How class loader work

All class loaders except the bootstrap class loader have a parent class loader. Moreover, all class loaders are of the type java.lang.ClassLoader.
The most important aspect is to correctly set the parent class loader. The parent class loader for any class loader is the class loader instance that loaded that class loader. (Remember, a class loader is itself a class!)
A class is requested out of a class loader using the loadClass() method. The internal working of this method can be seen from the source code for java.lang.ClassLoader, given below:


To set the parent class loader, we have two ways to do so in the ClassLoader constructor:



If the parent class loader is correctly set, whenever a class is requested out of a ClassLoader instance, if it cannot find the class, it should ask the parent first. If the parent cannot find it (which again means that its parent also cannot find the class, and so on), and if the findBootstrapClass0() method also fails, the findClass() method is invoked. The default implementation of findClass() will throw ClassNotFoundException and developers are expected to implement this method when they subclass java.lang.ClassLoader to make custom class loaders.

The default implementation of findClass() is shown below




Inside of the findClass() method, the class loader needs to fetch the byte codes from some arbitrary source. The source can be the file system, a network URL, a database, another application that can spit out byte codes on the fly, or any similar source that is capable of generating byte code compliant with the Java byte code specification.



Class loaders and their usage follow a few simple rules


  • Class loaders are hierarchically organized, where each one has a parent class loader, except the bootstrap class loader (the root).
  • Class loaders should (practically: must) delegate the loading of a class to the parent, but a custom class loader can define for itself when it should do so.
  • A class is defined by its class type and the effective class loader.
  • A class is only loaded once and then cached in the class loader to ensure that the byte code cannot change.
  • Any symbolic links are loaded by the effective class loader (or one of its ancestors), if this is not already done. The JVM can defer this resolution until the class is actually used.
  • An upcast of an instance to another class fails when the class of the instance and the class of the symbolic link do not match (meaning their class loaders do not match).


Why Do We Need our Own Class Loaders?
When your application is hosting other applications which are using same libraries in different versions in the same runtime (e.g. Tomcat). So you have to make sure that your classloader can provide different versions of the same class for each of these applications.

Using a different classloader than the System Classloader is required if you need to unload classes from memory, or to load classes than could change their definition at runtime. A typical case is an application that generates a class on the fly from an XML file, for example, and then tries to reload this class. Once a class is in the System Classloader, there is no way to unload it and have a new definition.

Tomcat 5 installs a variety of class loaders (that is, classes that implement java.lang.ClassLoader) to allow different portions of the container, and the web applications running on the container, to have access to different repositories of available classes and resources. Check this for more detail


Why write a ClassLoader?
If the JVM has a ClassLoader, then why would you want to write another one? Good question. The default ClassLoader only knows how to load class files from the local filesystem. This is fine for regular situations, when you have your Java program fully compiled and waiting on your computer.

But one of the most innovative things about the Java language is that it makes it easy for the JVM to get classes from places other than the local hard drive or network. For example, browsers use a custom ClassLoader to load executable content from a Web site. Anything you can think of to write that can generate Java bytecode can be integrated into your application.

Custom ClassLoader examples
If you've ever used the appletviewer included in the JDK or any Java-enabled browser, you've almost certainly used a custom ClassLoader.
What made this feat possible was the ability of the Java language to install a custom ClassLoader. The appletviewer contains a ClassLoader that, instead of looking in the local filesystem for classes, accesses a Web site on a remote server, loads the raw bytecode files via HTTP, and turns them into classes inside the JVM.
The ClassLoaders in browsers and appletviewers do other things as well: they take care of security and keep different applets on different pages from interfering with each other.


The ClassLoader structure
Overview
A ClassLoader's basic purpose is to service a request for a class. The JVM needs a class, so  it asks the ClassLoader, by name, for this class, and the ClassLoader attempts to return a Class object that represents the class.
By overriding different methods corresponding to different stages of this process, you can create a custom ClassLoader.

Method loadClass
ClassLoader.loadClass() is the entry point to the ClassLoader. Its signature is as follows:
Class loadClass( String name, boolean resolve );
The name parameter specifies the name of the class that the JVM needs, in package notation, such as Foo or java.lang.Object.

The resolve parameter tells the method whether or not the class needs to be resolved. You can think of class resolution as the task of completely preparing the class for execution. Resolution is not always needed. If the JVM needs only to determine that the class exists or to find out what its superclass is, then resolution is not required.

Method defineClass
The defineClass method is the central mystery of the ClassLoader. This method takes a raw array of bytes and turns it into a Class object. The raw array contains the data that, for example, was loaded from the filesystem or across the network.

defineClass takes care of a lot of complex, mysterious, and implementation-dependent aspects of the JVM -- it parses the bytecode format into a run-time data structure, checks for validity, and so on. But don't worry, you don't have to write it yourself. In fact, you couldn't override it even if you wanted to because it's marked as final.

Method findSystemClass
The findSystemClass method loads files from the local filesystem. It looks for a class file in the local filesystem, and if it's there, turns it into a class using defineClass to convert raw bytes into a Class object. This is the default mechanism for how the JVM normally loads classes when you are running a Java application.

For our custom ClassLoader, we'll use findSystemClass only after we've tried everything else to load a class. The reason is simple: our ClassLoader is responsible for carrying out special steps for loading classes, but not for all classes. For example, even if our ClassLoader loads some classes from a remote Web site, there are still plenty of basic Java libraries on the local machine that must also be loaded. These classes aren't our concern, so we ask the JVM to load them in the default way: from the local filesystem. This is what findSystemClass does.

Method resolveClass
As I mentioned previously, loading a class can be done partially (without resolution) or completely (with resolution). When we write our version of loadClass, we may need to call resolveClass, depending on the value of the resolve parameter to loadClass 

Method findLoadedClass
findLoadedClass serves as a cache: when loadClass is asked to load a class, it can call this method to see if the class has already been loaded by this ClassLoader, saving the trouble of reloading a class that has already been loaded. This method should be called first.

Putting it all together
  1. Call findLoadedClass to see if we have already loaded the class.
  2. If we haven't loaded the class, we do special magic to get the raw bytes.
  3. If we have the raw bytes, call defineClass to turn them into a Class object.
  4. If we don't have the raw bytes, then call findSystemClass to see if we can get the
  5. class from the local filesystem.
  6. If the resolve parameter is true, call resolveClass to resolve the Class object.
  7. If we still don't have a class, throw a ClassNotFoundException.
  8. Otherwise, return the class to the caller.

Classfile verification
  • The code may not have been generated by a trusted compiler
  • The code may not have been originated from Java source
  • Other classes may have changed since this class was compiled
  • Load-time verification reduces run-time overheads
Verification at load time
  • Verify that the file is a .class file and that all section/attributes are well-formed and of the proper length
  • Verify the non-code portions of the class
    Final methods/classes are not overridden
    Every class has a superclass
    The constant pool is valid and contains the necessary values
  • Verify the code
    The size and types of the operand stack are fixed at any point and no overflow or underflow occurs
    Local variables are valid and of the correct type
    Methods are invoked with the appropriate arguments
    Fields are assigned values of the correct type
    Arguments to JVM opcodes are of correct types
Verification at run time
  • Verify that the current class can access fields and methods in other classes
    Attempt to perform these checks only once
  • Attempt to perform these checks only once
  • Verify that an object assigned to a variable or field is of compatible type
    That’s why you see ClassCastException from  time to time…

How to check which classes are loaded
Passing the -verbose:class switch to the java command will print each class loaded and where it was loaded from.

Thread Communication with wait(), notidy(), notifyAll()
Daemon thread in Java
Upcasting and DownCasting in java


If you know anyone who has started learning java, why not help them out! Just share this post with them. 
Thanks for studying today!...

9 comments:

  1. Thanks, nice reading about Java guts.

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. It was really a wonderful article and I was really impressed by reading this blog. We are giving all software Course Online Training. The HTML5 Courses in Chennai is one of the reputed Training institute in Chennai. They give professional and real time training for all students.

    ReplyDelete
  4. Very informative stuff... Thanks :)

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete