Saturday, July 09, 2005

WebSphere 5.x Classloaders.

Picture 1 Java Classloader Hierarchy.


Picture 2 WebSphere Classloader Hierarchy.

Java Classloaders

The standard Java (JSE) VM has three classloaders: the bootstrap classloader, the extensions classloader, and the system classloader.

Bootstrap Classloader: The bootstrap classloader is responsible for loading the core Java libraries, that is /lib/rt.jar and /lib/i18n.jar. This classloader, which is part of the core JVM, is written in native code.

Extensions classloader: The extensions classloader is responsible for loading the code in the extensions directories (/lib/ext or any other directory specified by the java.ext.dirs system property). This classloader is implemented by the sun.misc.Launcher$ExtClassLoader class.

System Classloader: The system classloader is responsible for loading the code that is found on java.class.path, which ultimately maps to the system CLASSPATH variable. This classloader is implemented by the sun.misc.Launcher$AppClassLoader class.

Picture 1 shows the standard Java classloader hierarchy.

Delegation is a key concept to understand when dealing with classloaders. It states which classloader in the classloader hierarchy loads a class. By default when a Java program needs a class, the context (or current) classloader delegates class loading to its parent before trying to load the class itself. This is the default policy for standard JVM classloaders. For example if the system classloader needs to load a class, it first delegates to the extensions classloader, which in turn delegates to the bootstrap classloader. If the parent classloader cannot load the class, the child classloader tries to find the class in its own repository. In this manner, a classloader is only responsible for loading classes that its ancestors cannot load. A classloader can only find classes up in the hierarchy, not down. This is a very important concept because at runtime if a class tries to load a class not visible to the classloader that loaded it or any of it parents then NoClassDefFoundError will be thrown.

WebSphere 5.x Classloaders

WebSphere provides several custom delegated classloaders: the WebSphere extensions classloader and different application classloaders.

WebSphere Application Server 5.x classloader hierarchy is shown in picture 2 above.

In general each enterprise application (EAR) gets its own classloader and each web application (WAR) within an EAR or without an EAR i.e. standalone WAR gets its own classloader. All EJB JAR files within an application are always loaded by the same classloader. The application classloader policy and WAR classloader policy control the actual runtime classloader hierarchy.

WebSphere Extensions Classloader

The WebSphere extensions classloader, whose parent is the Java system classloader, is primarily responsible for the loading of the WebSphere class libraries in the following directories:

- $WAS_HOME/java/lib
- $WAS_HOME/classes (Runtime Class Patches directory, or RCP)
- $WAS_HOME/lib (Runtime classpath directory, or RP)
- $WAS_HOME/lib/ext (Runtime Extensions directory, or RE)

The WebSphere runtime is loaded by the WebSphere extensions classloader based on the ws.ext.dirs system property, which is initially derived from the WS_EXT_DIRS environment variable set in the setupCmdLine script file found in $WAS_HOME/bin directory. The default value of ws.ext.dirs is the following:

SET WAS_EXT_DIRS=%JAVA_HOME%/lib;%WAS_HOME%/classes;%WAS_HOME%/lib;
%WAS_HOME%/lib/ext;%WAS_HOME%/web/help;
%ITP_LOC%/plugins/com.ibm.etools.ejbdeploy/runtime

The RCP directory is intended to be used for fixes and other APARs (IBM terminology for patches) that are applied to the application server runtime. These patches override any copies of the same files lower in the RP and RE directories. The RP directory contains the core application server runtime files. The bootstrap classloader first finds classes in the RCP directory then in the RP directory. The RE directory is used for extensions to the core application server runtime. Each directory listed in the ws.ext.dirs environment variable is added to the WebSphere extensions classloaders classpath. In addition, every JAR file and/or ZIP file in the directory is added to the classpath. You can extend the list of directories/files loaded by the WebSphere extensions classloaders by setting a ws.ext.dirs custom property to the Java virtual machine settings of an application server.

Application Extensions Classloader

In WebSphere Application Server Version 4.0, one could drop JAR files under /lib/app to share those JARS across all applications. This is still supported, but is not recommended for new deployment. It is mainly provided for compatibility with WebSphere V4.0 deployments. The main issue with this classloader is that its contents are seen by all applications. The recommended approach is to use shared libraries, which have a different behavior.

Shared Libraries

It is recommended that shared libraries be used to point to a set of JARs (for example, a framework), and associate those JARs to an application or application server.

Shared libraries consist of a symbolic name, a Java classpath, and a native path (for loading JNI libraries), and can be defined at the cell, node, or server level. However, defining a library at one of the three levels does not cause the library to be loaded. The library must associated to an application and/or application server in order for the classes represented by the shared library to be loaded.

If shared library is associated to an application (EAR), the JARs listed on the shared library path are loaded by the application classloader (together with EJB JARs, RARs and dependency JARs). If the the shared library is associated at the application server level, the JARs listed on the shared library path are loaded by a specific classloader (which you have to define).

Classloading and Delegation mode

There are two possible values for a classloader loading mode: PARENT_FIRST and PARENT_LAST. The default value for classloading mode is PARENT_FIRST. This policy causes the classloader to first delegate the loading of classes to its parent classloader before attempting to load the class from its local classpath. This is the default policy for standard JVM classloaders. If the classloading policy is set to PARENT_LAST, the classloader attempts to load classes from its local classpath before delegating the classloading to its parent. This policy allows an application classloader to override and provide its own version of a class that exists in the parent classloader. Delegation mode can be set for the following classloaders: application classloader, WAR classloader, and shared library classloader.

Classloader Policies

For each application server in the system, the application classloader policy can be set to Single or Multiple.

Single: When the application classloading policy is set to Single, a single application classloader is used to load all EJBs, dependency JARs, and shared libraries within the application server (JVM). If the WAR classloader loading policy has been set to Application, the Web module contents for this particular application are also loaded by this single classloader.

Multiple: When the application classloading policy is set to Multiple, each application will receive its own classloader for loading EJBs, dependency JARs, and shared libraries. Depending on whether the WAR classloader loading policy is set to Module or Application, the Web module may or may not receive its own classloader.

For web application, the WAR classloader policy can be set to Module or Application.

Module: When the WAR classloading policy is set to Module, the Web module gets its own WAR classloader and it loads classes for the Web module.

Application: When the WAR classloading policy is set to Application, the Web module does not get its own WAR classloader. The Web module classes are loaded by application classloader (either single or multiple guided by application classloading policy).

Reloadable Classloaders

The application (EAR classloader) and the Web module classloaders (WAR classloader) are reloadable classloaders. They monitor changes in the application code to automatically reload modified classes. This behavior can be altered at deployment time.


Comments: Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?