bea.com | products | dev2dev | support | askBEA
 Download Docs   Site Map   Glossary 
Search

Developing WebLogic Server Applications

 Previous Next Contents Index View as PDF  

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

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 parent classloaders 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 root 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.

Note: What BEA refers to as a "system classloader" is often referred to as the "application classloader" in contexts outside of WebLogic Server. When discussing classloaders in WebLogic Server, BEA uses the term "system" to differentiate from classloaders related to J2EE applications (which BEA refers to as "application classloaders").

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 current classloader asks its parent for 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. This delegation model is followed to avoid multiple copies of the same form being loaded. Multiple copies of the same class can lead to a ClassCastException.

Classloaders ask their parent classloader to load a class before attempting to load the class themselves. Classloaders in WebLogic Server that are associated with Web applications can be configured to check locally first before asking their parent for the class. This allows Web applications to use their own versions of third-party classes, which might also be used as part of the WebLogic Server product. The following section discusses this in more detail.

PreferWebInfClasses Element

The WebAppComponentMBean contains a PreferWebInfClasses element. By default, this element is set to False. When you set this element to True, this subverts the classloader delegation model so that class definitions from the Web application are loaded in preference to class definitions in higher-level classloaders. This allows a Web application to use its own version of a third-party class, which might also be part of WebLogic Server.

When using this feature, you must be careful not to mix instances created from the Web applications class definition with issuances created from the server's definition. If such instances are mixed, a ClassCastException results.

Listing 4-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

Java classloaders do not have any standard mechanism to undeploy or unload a set of classes, nor can they load new versions of classes. In order to make updates to classes in a running virtual machine, the classloader that loaded the changed classes must be replaced with a new classloader. When a classloader is replaced, all classes that were loaded from that classloader (or any classloaders that are offspring of that classloader) must be reloaded. Any instances of these classes must be reinstantiated.

In WebLogic Server, each application has a hierarchy of classloaders that are offspring of the system classloader. These hierarchies allow applications or parts of applications to be individually reloaded without affecting the rest of the system. This is the topic of the next section.

 


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. The following may be part of an EAR or can be loaded as standalone applications:

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 code only has visibility to classes loaded by the classloader associated with the application (or component) and classes that are loaded by classloaders that are ancestors of the application (or component) classloader. This allows WebLogic Server to host multiple isolated applications within the same JVM.

Application Classloader Hierarchy

WebLogic Server automatically creates a hierarchy of classloaders when an application is deployed. The root classloader in this hierarchy 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 4-1 WebLogic Server Classloading


 


 

If your application includes servlets and JSPs that use EJBs:

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 JSP class. The JSP class obtains its own classloader, which is a child of the Web application classloader. This allows JSPs to be individually reloaded.

Custom Module Classloader Hierarchies

You can create custom classloader hierarchies for an application allowing for better control over class visibility and reloadability. You achieve this by defining a classloader-structure element in the weblogic-application.xml deployment descriptor file.

The following diagram illustrates how classloaders are organized by default for WebLogic applications. An application level classloader exists where all EJB classes are loaded. For each Web module, there is a separate child classloader for the classes of that module.

For simplicity, JSP classloaders are not described in the following diagram.

Figure 4-2 Standard Classloader Hierarchy


 


 

This hierarchy is optimal for most applications, because it allows call-by-reference semantics when you invoke on EJBs. It also allows Web modules to be independently reloaded without affecting other modules. Further, it allows code running in one of the Web modules to load classes from any of the EJB modules. This is convenient, as it can prevent a Web module from including the interfaces for EJBs that is uses. Note that some of those benefits are not strictly J2EE-compliant.

The ability to create custom module classloaders provides a mechanism to declare alternate classloader organizations that allow the following:

Declaring the Classloader Hierarchy

You can declare the classloader hierarchy in the WebLogic-specific application deployment descriptor weblogic-application.xml. For instructions on how to edit deployment descriptors, refer to the "WebLogic Builder Online Help."

The DTD for this declaration is as follows:

Listing 4-2 Declaring the Classloader Hierarchy

<!ELEMENT classloader-structure (module-ref*, classloader-structure*)>
<!ELEMENT module-ref (module-uri)>
<!ELEMENT module-uri (#PCDATA)>

The top-level element in weblogic-application.xml includes an optional classloader-structure element. If you do not specify this element, then the standard classloader is used. Also, if you do not include a particular module in the definition, it is assigned a classloader, as in the standard hierarchy. That is, EJB modules are associated with the application Root classloader and Web Modules have their own classloaders.

The classloader-structure element allows for the nesting of classloader-structure stanzas, so that you can describe an arbitrary hierarchy of classloaders. There is currently a limitation of three levels. The outermost entry indicates the application classloader. For any modules not listed, the standard hierarchy is assumed.

Note: JSP classloaders are not included in this definition scheme. JSPs are always loaded into a classloader that is a child of the classloader associated with the Web module to which it belongs.

For more information on the DTD elements, refer to Application Deployment Descriptor Elements.

The following is an example of what a classloader declaration would look like:

Listing 4-3 Example Classloader Declaration

<classloader-structure>
    <module-ref>
        <module-uri>ejb1.jar</module-uri>
    </module-ref>
    <module-ref>
        <module-uri>web3.war</module-uri>
    </module-ref>
    <classloader-structure>
        <module-ref>
            <module-uri>web1.war</module-uri>
        </module-ref>
    </classloader-structure>
    <classloader-structure>
        <module-ref>
            <module-uri>ejb1.jar</module-uri>
        </module-ref>
        <module-ref>
            <module-uri>web2.war</module-uri>
        </module-uri>
        <classloader>
            <module-ref>
                <module-uri>web4.war</module-uri>
            </module-ref>
        </classloader>
        <classloader>
            <module-ref>
                <module-uri>ejb2.jar</module-uri>
            </module-ref>
        </classloader>
    </classloader>
</classloader>

The organization of the nesting indicates the classloader hierarchy. The above stanza leads to a hierarchy shown in the following diagram:

Figure 4-3 Example Classloader Hierarchy


 


 


 

User-defined Classloader Restrictions

The purpose of this feature is to provide you with better control over what is reloadable and provide inter-module class visibility. This is primarily intended to be a developer feature. It is useful for iterative development, but the reloading aspect of this feature is not recommended for production use, since it is possible to corrupt a running application if an update includes invalid elements. Custom classloader arrangements for namespace separation and class visibility are acceptable for production use. However, programmers should be aware that the J2EE specifications say that applications should not depend on any given classloader organization.

Some classloader hierarchies can cause modules within an application to behave more like modules in two separate applications. For example, if you place an EJB in its own classloader so that it can be reloaded individually, you receive call-by-value semantics rather than the call-by-reference optimization BEA provides in our standard classloader hierarchy. Also note that if you use a custom hierarchy, you might end up with stale references. Therefore, if you reload an EJB module, you should also reload calling modules.

There are some restrictions to creating user-defined module classloader hierarchies; these are discussed in the following sections.

Servlet Reloading Disabled

If you use a custom classloader hierarchy, servlet reloading is disabled for Web applications in that particular application.

Nesting Depth

Nesting is limited to three levels (including the application classloader). Deeper nestings lead to a deployment exception.

Module Types

Custom classloader hierarchies are currently restricted to Web and EJB modules.

Duplicate Entries

Duplicate entries lead to a deployment exception.

Interfaces

With our standard classloader hierarchy, the interfaces for EJB are available to all modules in the application. This means that other modules can invoke on an EJB, even though they do not include the interface classes in their own module. This is possible since EJBs are always loaded into the root classloader and all other modules either share that classloader or have a classloader that is a child of that classloader.

With the custom classloader feature, you can configure a classloader hierarchy so that a callee's classes are not visible to the caller. In this case, the calling module must include the interface classes. This is the same requirement that exists when invoking on modules in a separate application.

Call-by-value Semantics

The standard classloader hierarchy provided with WebLogic Server allows for calls between modules within an application to use call-by-reference semantics. This is because the caller is always using the same classloader or a child classloader of the callee. With this feature, it is possible to configure the classloader hierarchy so that two modules are in separate branches of the classloader tree. In this case, call-by-value semantics are used.

In-flight Work

It is important to be aware that the classloader switch required for reloading is not atomic across modules. In fact, updates to applications are in general not atomic. For this reason, it is possible that different in-flight operations might end up accessing different versions of classes depending on timing.

Development Use Only

This feature is intended for development use. Since updates are not atomic, this feature is not suitable for production use.

Individual EJB Classloader for Implementation Classes

WebLogic Server allows you to reload individual EJB modules without forcing other modules to be reloaded at the same time and having to redeploy the entire EJB module. This feature is similar to how JSPs are currently reloaded in the WebLogic Server servlet container.

Since EJB classes are invoked through an interface, it is possible to load individual EJB implementation classes in their own classloader. This way, these classes can be reloaded individually without having to redeploy the entire EJB module. Below is a diagram of what the classloader hierarchy for a single EJB module would look like. The module contains two EJBs (Foo and Bar). This would be a sub-tree of the general application hierarchy described in the previous section.

Figure 4-4 Example Classloader Hierarchy for a Single EJB Module


 

To perform an incremental update (partial upgrade), use the following command line:

Listing 4-4

java weblogic.Deployer -adminurl url -user user -password password 
-name myapp -redeploy myejb/foo.class

After the -redeploy command, you provide a list of files relative to the root of the exploded application that you want to update. This might be the path to a specific element (as above) or a module (or any set of elements and modules). For example:

Listing 4-5

java weblogic.Deployer -adminurl url -user user -password password 
-name myapp -redeploy mywar myejb/foo.class anotherejb

Given a set of files to be updated, the system tries to figure out the minimum set of things it needs to redeploy. Redeploying only an EJB impl class causes only that class to be redeployed. If you specify the whole EJB (in the above example, anotherejb) or if you change and update the EJB home interface, the entire EJB module must be redeployed.

Depending on the classloader hierarchy, this may lead to other modules being redeployed. Specifically, if other modules share the EJB classloader or are loaded into a classloader that is a child to the EJB's classloader (as in our standard classloader module) then those modules are also 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.

 


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

WebLogic Server provides a location within an EAR file where you can store shared utility classes. Place utility JAR files in the APP-INF/lib directory and individual classes in the APP-INF/classes directory. (Do not place JAR files in the /classes directory or classes in the /lib directory.) These classes are loaded into the root classloader for the application, making them visible to all components within the EAR.

This feature obviates the need to place utility classes in the system classpath or place classes in an EJB JAR file (which depends on the standard WebLogic Server classloader hierarchy). Be aware that using this feature is subtly different from using the manifest Class-Path described in the following section. With this feature, class definitions are shared across the application. With manifest Class-Path, the classpath of the referencing module is simply extended, which means that separate copies of the classes exist for each module.

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

 

Back to Top Previous Next