Wednesday, December 28, 2005

Classloading in Appservers

Anyone creating a web-application in an application server, might have wondered, how the servlet engine did not muddle up classes from different web-apps. Take the case of a jsp index.jsp or com.xxx.Controller which might be present in nearly all web-apps. When we deploy 2 webapps having these two classes, how is the server using the correct index.jsp/Controller, when a request comes in.

The point to note is that since a class is loaded only once by a classloader, Controller if loaded once will stay on in the memory and same copy will be reused. If the application server used only one class loader to load all classes then we would show only one version of index.jsp for all webapps.

To solve this, it becomes clear each web-app needs its own classloader. Good. Now knowing this, I thot if i compile Controller & put it some where on the class path, then each web-app class loader will still refuse to pick up the Controller in its deployed location. Why ? Because the class loader documentation says all classloaders typically delegate the request to the parent before attempting to resolve it itself. The classloader hierarchy looks like this ...

Bootstrap classloader
|
Extension classloader (loads extension classes...new version of jaxp.jar..)
|
System classloader (loads classes from classpath)
|
EAR Classloader
|
WAR Classloade

So if the system class loader loads Controller from classpath it prevents all the WAR classloaders from loading Controller ever. The only way out is to prevent system classloader from loading Controller from classpath. How? By using our own implementation of the classloader. This lead me to my next question..how do i swap the default system class loader with my own implementation ?

The answer is quite simple. All we need to do is set the propery java.system.class.loader to the desired system classloader. Say we do java -Djava.system.class.loader=my.test.SimpleClassLoader then the class loader hierarchy now becomes ..

Bootstrap classloader
|
Extension classloader (loads extension classes...new version of jaxp.jar..)
|
Default System classloader (can load classes from classpath)
|
System classloader (my.test.SimpleClassLoader)
|
EAR Classloader
|
WAR Classloader

Then i found out that the system classloaders in most app servers is designed to load only those package names that fit some predefine rules like javax.ejb.* etc and load classes only from those selected packages. They also delegate loading core java classes to the boostrap loader. These classloaders in addition do not delegate to parent for other requests. This solves most of the questions raised !

Quite a long post, makes me remember the stories we wrote in our history exams ! Ok, more details on how default system class loaders work and how class sharing between select web-apps can be done in the future.

For knowing more on classloaders read this article

Subscribe to comments for this post

No comments:

 
Clicky Web Analytics