bea.com | products | dev2dev | support | askBEA

Download Docs | Site Map | Glossary
Search

Developing WebLogic Server Applications

WebLogic Server Application Classloading

The following sections provide an overview of Java classloaders, followed by details about WebLogic Server J2EE application classloading.

- Java Classloader Overview

- WebLogic Server Application Classloader Overview

- Resolving Class References Between Components and Applications

Java Classloader Overview

Classloaders are a fundamental component of the Java language. A classloader is a part of the Java virtual machine (JVM) that loads classes into memory; it is the class responsible for finding and loading class files at run time. Every successful Java programmer needs to understand classloaders and their behavior. This section provides an overview of Java classloaders.

Java Classloader Hierarchy

Classloaders contain a hierarchy with a parent classloader and child classloaders. The relationship between parent and child classloaders is analogous to the object relationship of super classes and subclasses. The bootstrap classloader is the parent of the Java classloader hierarchy. The Java virtual machine (JVM) creates the bootstrap classloader, which loads the Java development kit (JDK) internal classes and java.* packages included in the JVM. (For example, the bootstrap classloader loads java.lang.String.)

The extensions classloader is a child of the bootstrap classloader. The extensions classloader loads any JAR files placed in the extensions directory of the JDK. This is a convenient means to extending the JDK without adding entries to the classpath. However, anything in the extensions directory must be self-contained and can only refer to classes in the extensions directory or JDK classes.

The system classpath classloader extends the JDK extensions classloader. The system classpath classloader loads the classes from the classpath of the JVM. Application-specific classloaders (including WebLogic Server classloaders) are children of the system classpath classloader.

Loading a Class

Classloaders use a delegation model when loading a class. The classloader implementation first checks to see if the requested class has already been loaded. This class verification improves performance in that the cached memory copy is used instead of repeated loading of a class from disk. If the class is not found in memory, the parent classloader loads the class. Only if the parent cannot load the class does the classloader attempt to load the class. If a class exists in both the parent and child classloaders, the parent version is loaded.

Note: Classloaders ask their parent classloader to load a class before attempting to load the class themselves. If needed, you can configure the classloader to check locally and then check the parent.

PreferWebInfClasses Element

The WebAppComponentMBean contains a PreferWebInfClasses element. By default, this element is set to False. Setting this element to True subverts the classloader delegation model and makes it very easy to obtain the same class loaded into both the Web application and system classloader, which in turn makes it very easy to obtain a ClassCastException.

Some users prefer to set this to True to override BEA implementations of various services (most commonly, XML processing classes such as XERCES). If you choose to set this element to True, be very careful not to mix instances of classes loaded from different classloaders.

Listing 3-1 PreferWebInfClasses Element

>     /**

>     * If true, classes located in the WEB-INF directory of a web-app will be loaded in preference to classes loaded in the application or system classloader.

>     * @default false

>     */

>     boolean isPreferWebInfClasses();

>     void setPreferWebInfClasses(boolean b);

Changing Classes in a Running Program

WebLogic Server allows you to deploy newer versions of application components such as EJBs while the server is running. This process is known as hot-deploy or hot-redeploy and is closely related to classloading

When you deploy a new version of an application, a new application classloader is created. This scheme works as long as the application classes are being loaded by the new classloader. If a class is in the system classpath, it cannot be changed while the server is running.

Note: Java classloaders do not have any standard mechanism to undeploy or unload a set of classes; nor can they load new versions of classes. One way to get around this is to create an application-specific classloader as a child of the classpath classloader.

WebLogic Server Application Classloader Overview

This section provides an overview of the WebLogic Server application classloaders.

Application Classloading

WebLogic Server classloading is centered on the concept of an application. An application is normally packaged in an Enterprise Archive (EAR) file containing application classes. Everything within an EAR file is considered part of the same application. Other applications include:

- An Enterprise JavaBean (EJB) JAR file

- A Web Application WAR file

Note: For information on Resource Adapter RAR files and classloading, see About Resource Adapter Classes.

If you deploy an EJB JAR file and a Web Application WAR file separately, they are considered two applications. If they are deployed together within an EAR file, they are one application. You deploy components together in an EAR file for them to be considered part of the same application.

Make sure that no resource-adapter specific classes exist in your WebLogic Server system classpath. If you need to use resource adapter-specific classes with Web components (for example, an EJB or Web application), you must bundle these classes in the corresponding component's archive file (for example, the JAR file for EJBs or the WAR file for Web applications).

Every application receives its own classloader hierarchy; the parent of this hierarchy is the system classpath classloader. This isolates applications so that application A cannot see the classloaders or classes of application B. In classloaders, no sibling or friend concepts exist. Application classloaders can only see their parent classloader, the system classpath classloader. This allows WebLogic Server to host multiple isolated applications within the same JVM.

Application Classloader Hierarchy

WebLogic Server automatically creates a set of classloaders when an application is deployed. The base application classloader loads any EJB JAR files in the application. A child classloader is created for each Web Application WAR file.

Because it is common for Web Applications to call EJBs, the WebLogic Server application classloader architecture allows JavaServer Page (JSP) files and servlets to see the EJB interfaces in their parent classloader. This architecture also allows Web Applications to be redeployed without redeploying the EJB tier. In practice, it is more common to change JSP files and servlets than to change the EJB tier.

The following graphic illustrates this WebLogic Server application classloading concept:

Figure 3-1 WebLogic Server Classloading

If your application includes servlets and JSPs that use EJBs:

- Package the servlets and JSPs in a WAR file

- Package the enterprise beans in an EJB JAR file

- Package the WAR and JAR files in an EAR file

- Deploy the EAR file

Although you could deploy the WAR and JAR files separately, deploying them together in an EAR file produces a classloader arrangement that allows the servlets and JSPs to find the EJB classes. If you deploy the WAR and JAR files separately, WebLogic Server creates sibling classloaders for them. This means that you must include the EJB home and remote interfaces in the WAR file, and WebLogic Server must use the RMI stub and skeleton classes for EJB calls, just as it does when EJB clients and implementation classes are in different JVMs. This concept is discussed in more detail in the next section Application Classloading and Pass by Value or Reference.

Note: The Web application classloader contains all classes for the Web application except for the servlet implementation classes and JSPs. Each servlet implementation class and JSP class obtains its own classloader, which is a child of the Web application classloader. This allows servlets and JSPs to be individually reloaded.

Application Classloading and Pass by Value or Reference

Modern programming languages use two common parameter passing models: pass by value and pass by reference. With pass by value, parameters and return values are copied for each method call. With pass by reference, a pointer (or reference) to the actual object is passed to the method. Pass by reference improves performance because it avoids copying objects, but it also allows a method to modify the state of a passed parameter.

WebLogic Server includes an optimization to improve the performance of Remote Method Interface (RMI) calls within the server. Rather than using pass by value and the RMI subsystem's marshalling and unmarshalling facilities, the server makes a direct Java method call using pass by reference. This mechanism greatly improves performance and is also used for EJB 2.0 local interfaces.

RMI call optimization and call by reference can only be used when the caller and callee are within the same application. As usual, this is related to classloaders. Since applications have their own classloader hierarchy, any application class has a definition in both classloaders and receives a ClassCastException error if you try to assign between applications. To work around this, WebLogic Server uses call by value between applications, even if they are within the same JVM.

Note: Calls between applications are slower than calls within the same application. Deploy components together as an EAR file to enable fast RMI calls and use of the EJB 2.0 local interfaces.

The following is a list of pass-by-value and pass-by-reference parameters called by EJB versions 2.0 and 1.1.

Table 3-1 Parameters Called by EJB Version 2.0

Packaging | Called Interface | Default Call Type | Effect of enable-call-by-reference
--- | --- | --- | ---
Caller WebApp/EJB are in an EAR file | Local Remote | Pass-by-Reference Pass-by-Value | Pass-by-Value if False Pass-by-Reference if True
Caller EJB and called EJB are in the same JAR file, not the same EAR file | Local Remote | Pass-by-Reference Pass-by-Value | Pass-by-Value if False Pass-by-Reference if True
Caller WebApp/EJB and called EJB are in separate deployment module (EAR/JAR) | Local Remote | Pass-by-Value Pass-by-Value | N/A N/A

Table 3-2 Parameters Called by EJB Version 1.1

Packaging | Called Interface | Default Call Type | Effect of enable-call-by-reference
--- | --- | --- | ---
Caller WebApp/EJB are in an EAR file | Remote | Pass-by-Reference | Pass-by-Value if False
Caller EJB and called EJB are in the same JAR file, not the same EAR file | Remote | Pass-by-Reference | Pass-by-Value if False
Caller WebApp/EJB and called EJB are in separate deployment module (EAR/JAR) | Remote | Pass-by-Value | N/A

Resolving Class References Between Components and Applications

Your applications may use many different Java classes, including enterprise beans, servlets and JavaServer Pages, utility classes, and third-party packages. WebLogic Server deploys applications in separate classloaders to maintain independence and to facilitate dynamic redeployment and undeployment. Because of this, you need to package your application classes in such a way that each component has access to the classes it depends on. In some cases, you may have to include a set of classes in more than one application or component. This section describes how WebLogic Server uses multiple classloaders so that you can stage your applications successfully.

About Resource Adapter Classes

Make sure that no resource-adapter specific classes exist in your WebLogic Server system classpath. If you need to use resource adapter-specific classes with Web components (for example, an EJB or Web application), you must bundle these classes in the corresponding component's archive file (for example, the JAR file for EJBs or the WAR file for Web applications).

Packaging Shared Utility Classes

Applications usually have shared utility classes. If you create or acquire utility classes that you will use in more than one application, you must package them with each application as separate JAR files. The JAR files should be self contained and not have any references to the classes in the EJB or Web components. Common types of shared utility classes are data transfer objects or JavaBeans, which are passed between the Web tier and EJB tier.

Alternatively, you can add shared utility classes to the Java system classpath by editing the java command in the script that runs WebLogic Server. If you modify your utility classes and they are in the Java system classpath, however, you will have to restart WebLogic Server after you modify the utility classes.

Classes that WebLogic Server uses during startup must be in the Java system classpath. For example, JDBC drivers used for connection pools must be in the classpath when you start WebLogic Server. Again, if you need to modify classes in the Java system classpath, or modify the classpath itself, you will have to restart WebLogic Server after you modify the classes or the classpath.

Manifest Class-Path

The J2EE specification provides the manifest Class-Path entry as a means for a component to specify that it requires an auxiliary JAR of classes. You only need to use this manifest Class-Path entry if you have additional supporting JAR files as part of your EJB JAR or WAR file. In such cases, when you create the JAR or WAR file, you must include a manifest file with a Class-Path element that references the required JAR files.

The following is a simple manifest file that references a utility.jar file:

>     Manifest-Version: 1.0 [CRLF]
>     Class-Path: utility.jar [CRLF]

In first line of the manifest file, you must always include the Manifest-Version attribute, followed by a new line (CR | LF |CRLF) and then the Class-Path attribute. More information about the manifest format can be found at: http://java.sun.com/j2se/1.4/docs/guide/jar/jar.html#JAR

The manifest Class-Path entries refer to other archives relative to the current archive in which these entries are defined. This structure allows multiple WAR files and EJB JAR files to share a common library JAR. For example, if a WAR file contains a manifest entry of y.jar, this entry should be next to the WAR file (not within it) as follows:

>     /<directory>/x.war

>     /<directory>/y.jars

The manifest file itself should be located in the archive at META-INF/MANIFEST.MF.

For more information, see http://java.sun.com/docs/books/tutorial/jar/basics/manifest.html