Tuesday, April 14, 2009

The mystery behind Java class loaders ..

I have been playing around with Java class loaders for few weeks by now .. and it still doesn't feel good. There are number of articles on the Internet that describes the internals of Java class loaders but none of them answers few of my questions.

First the basics .. A class loader is an entity in the JVM, that is responsible for reading the Java byte code from the .class file on the file system and creating a Java Class in memory. The java program can create objects or use static methods of a class only after it is loaded by a class loader. To add to the complexity, there is not a single class loader to load all the classes. In fact, there is hierarchy of them. First there is the bootstrap class loader which basically loads all the Java system classes (all those under java.lang package). Just below it is the Extensions class loader which loads all jar files you put inside Java home ext directory. And then comes the System class path class loader which loads all the classes present in the class path. If you provide any JAR files or classes using '-cp' option they are loaded by this class loader. For stand alone Java applications, the class loader hierarchy ends here.

Before going into Application servers, let me talk about the delegation model. As I described before, there is a parent-child relationship among different class loaders. When a class loader is asked to load a class, it first delegates the job to it's parent and only when the parent could not load the class, it tries to find and load it from it's own class path. For instance when you use java.util.Date in your program, the System class path class loader is first asked to load this class. Before trying to load by itself, it first delegates to the Extension class loader which further delegates to the boot strap class loader. The boot strap class loader does not have a parent, so it tries to load it by itself. It obviously finds the class in it's class path and loads the class. On the other hand, if you try to use a class from a third party library, which you specified in your class path on the command line, it goes all the way to the boot strap class loader and comes back to the System class path class loader because, no ancestor will find this class in their class path. System class path class loader obviously finds it in it's own class path and loads it for you.

Now, application servers create additional class loaders to provide run time isolation between different applications. So, just below the System class path class loader, there are several Application Class loaders one for each application deployed. I am speaking of Enterprise Applications packaged as EAR files and not stand alone java applications here. As you might have grasped by now, there is no sibling relationship among class loaders. So, an enterprise application can see (at runtime) all the classes in it's own class path, in the application server's class path, Java extension directory and Java system classes. But it cannot see classes in the class path of another Application.

If an enterprise application contains a web module, then most application servers create a separate class loader to load classes from that WAR file. So, different web applications in the same Enterprise application cannot see each others classes.

To be continued ..

0 comments: