WebSphere Application Server classloaders

This article provides information about how WebSphere Application Server uses classloaders to load various system and runtime resources. To make sure your application code runs correctly and with the appropriate characteristics, follow the information below. The following topics are covered:

The classloaders and their search orders

The relationship among the classloaders represents the fact that classes loaded by a particular classloader can reference other classes as long as these other classes can be loaded by the same classloader or any of its ancestors (but not its children).

After a class is loaded, its scope is everything in scope for its classloader plus everything that is in scope for its parent classloader. Scope does not extend downward in the classloader hierarchy. For example, JSP classes are not in scope (are not visible) for classes in the JVM classloader.

JVM runtime classloaders

The JVM classloaders, also called the system classloader, are provided by the JVM runtime. In JDK 1.3, there are three classloaders, which have the following hierarchy:

  1. boot classloader
    Loads the core JDK 1.3 runtime classes.
  2. extension classloader
    Loads JVM extensions. The classes loaded are defined by the value of the java.ext.dirs Java system property.
  3. user classloader
    Loads user classes. The classes loaded are defined by the value of the CLASSPATH environment variable or the -classpath Java option.

If you set the classpath for an application server, the value specified is appended to the classpath. You can use any of the following methods to set the classpath for an application server:

Because the JVM classloader is the parent of the WebSphere runtime classloader, it is important to note that the classes put in the system classpath are not able to load classes in the WebSphere Application Server runtime (including J2EE APIs). This means, for example, that you cannot have WebSphere Application Server components (such as servlets, JSPs, and enterprise beans) loaded by the JVM classloader, since they require WebSphere Application Server runtime classes such as javax.servlet.http.HttpServlet and javax.ejb.EJBHome. If you do this, for example, by placing your application classes on the system classpath, you get NoClassDefFound errors.

WebSphere Application Server runtime classloader

The WebSphere Applicatoin Server runtime classloader loads the WebSphere Application Server runtime (infrastructure). The classloader contents are defined by the ws.ext.dirs property, which should not be changed. Classes are loaded from the following locations, in the order listed:

  1. /QIBM/ProdData/WebASAdv4/classes
    This directory is used to provide iSeries-specific changes to the core WebSphere Application Server runtime.
  2. /QIBM/ProdData/WebASAdv4/lib and /QIBM/ProdData/WebASAdv4/lib/server
    These directories contain the core WebSphere Application Server runtime.
  3. /QIBM/UserData/WebASAdv4/instance/lib/ext, where instance is the name of your WebSphere Application Server instance
    This directory contains extensions to the core WebSphere Application Server runtime.

If you specify the ws.ext.dirs JVM system property for an application server (by using the System Property setting or a command line argument on the JVM Settings of the application server), the value specified is appended to the current ws.ext.dirs value.

Application extensions classloader

The application extensions classloader loads classes in the /QIBM/UserData/WebASAdv4/instance/lib/app subdirectory, where instance is the name of your WebSphere Application Server instance.

Classes that you want shared among all J2EE applications installed on the server should be placed here. Examples include:

Application classloaders

The application classloaders load the classes in your applications including servlets, enterprise beans, JavaServer Pages (JSP) files, JavaBeans, and supporting class libraries.

There are two kinds of classloaders used to load applications -- an EJB/Dependency classloader and Web module classloaders. The number and scope of these classloaders depends on the visibility setting of your application server.

EJB/Dependency classloader

This classloader includes the .jar files for all EJB modules and all of the .jar files specified in module classpaths.

By default, this classloader delegates to the parent classloader before attempting to load classes. You can change this behavior by setting the com.ibm.ws.classloader.ejbDelegationMode JVM system property (true is the default value). When a combined EJB/web classloader is used (when using Server or Application visibility), the EJB delegation value is ignored and the .war delegation value is used.

Web module classloaders

Web module classloaders include the .war file and its pieces, WEB-INF/classes and WEB-INF/lib.

Within the module classloader for the .war file, the search order is as follows:

  1. Root of the .war file
  2. WEB-INF/classes directory contents
  3. .jar files in the WEB-INF/lib directory

By default, .war module classloaders attempt to load classes before delegating to the parent classloader, except when using Application--J2EE visibility. With Application--J2EE visibility, .war module classloaders delegate to the parent classloader before attempting to load classes. You can change this behavior by setting the com.ibm.ws.classloader.warDelegationMode JVM system property.

When the delegation mode is true, classes are searched for in the following order:

  1. Application extensions classloader
  2. JVM runtime classloaders
  3. WebSphere runtime classloader
  4. EJB/Dependency classloader
  5. Web module classloaders

When the delegation mode is false, classes are searched for in the following order:

  1. Web module classloaders
  2. Application extensions classloader
  3. JVM runtime classloaders
  4. WebSphere runtime classloader
  5. EJB/Dependency classloader
Module visibility

The relationship among the classloaders implies that it is not usually possible to access the classes of one Web application from another Web application.

The application server settings include a property for specifying the module visibility, which determines the level of isolation among the various application components.

Note that the module visibility setting impacts whether you can port applications from previous WebSphere Application Server versions or other editions (from Advanced Single Server Edition Version 4.0 to Advanced Edition Version 4.0, for example) without reassembling the applications or changing the property value.

See the Module visibility topic for more information.

During EJB deployment

Classes needed during EJB deployment (such as application-defined exception classes or return values) should generally be packaged with the EJB in the EJB .jar file. In the case where this is not possible, you must specify additional options when deploying the application. If you do not, ClassNotFoundException and NoClassDefFound errors are generated. (In earlier versions of WebSphere Application Server, classes needed during deployment were placed on the Dependent classpath property of the Node object.) Specify the location of these dependent classes during deployment to solve this. If using the EJB deploy command-line tool, use the -cp option. If using the console or AAT to deploy, use the 'Dependent classpath' field on the deployment panel.

Note: These classpaths are not used during runtime. Place your classes in an appropriate location (determined by the information earlier in this page) to ensure they are found during runtime.

Guidelines for reloading classes

Dynamic reloading is affected by two factors: the module visibility setting and the classloader used to load the classes.

Dynamic reloading is directly affected by the classloader used to load the classes. Dynamic reloading can only be done if the class was loaded by a Web module classloader. Classes that are loaded by a system classloader, WebSphere runtime classloader, Application extension classloader, or EJB/Dependency classloader are not reloadable.

Reloading is available only in certain visibility settings. When using Application visibility, changes to .war modules will automatically cause the application to restart, therefore causing all classes to be reloaded. When using Application--J2EE or Compatibility visibility, reloading is disabled for EJBs and dependencies, but enabled for .wars. When using Server visibility, reloading is disabled for all classes. When using Module visibility, reloading is disabled for EJB modules, but enabled for .wars and dependencies.

Changes made to unreloadable classes require the application (if using Module, Application, or Application-J2EE visibility) or application server (if using Server or Compatibility visbility)to be restarted.

Java execution modes

Because all WebSphere components (servlets, JSPs, and enterprise beans) are loaded by an application classloader, WebSphere components do not use the direct execution (DE) capabilities of the OS/400 JVM. Java program (JVAPGM) objects are not used when running WebSphere component code. Classes loaded by a system classloader or WebSphere runtime classloader use DE capabilities and JVAPGM objects. Java user classloader caching can be used to allow WebSphere components to use permanent JVAPGM objects and DE capabilities, though this is not necessary for the vast majority of applications.

By default, application servers run with the Java system property java.compiler=jitc_de. This property is set by the ejbsvr.java.compiler property in the admin.properties file. The jitc_de value means that just-in-time compilation is done for any Java object for which a JVAPGM object does not exist (or cannot be used, in the case of WebSphere application classloaders). This setting provides the best overall performance.

It is possible to change application servers to use direct execution instead of JIT mode. Doing so results in longer startup times, because creation of the JVAPGM takes longer than creation of the JIT stubs. After the JVAPGMs are created, performance of direct execution may be slightly improved over JIT. To make an application server use direct execution for all classes, add two system properties on the JVM Settings tab of the application server:

It is also possible to have an application server use the interpreter only (no JIT). To make an application server use full interpretation for all WebSphere components, add a system property on the JVM Settings tab of the application server. Add property java.compiler with value NONE. Using the interpreter is slower during runtime, but is quicker at startup.

Guidelines for packaging classes

To avoid classloading problems, package your J2EE application appropriately, keeping the following tips in mind: