Skip Headers
Oracle® Containers for J2EE Developer's Guide
10g (10.1.3.5.0)
E13979-01
  Go To Documentation Library
Library
Go To Product List
Product
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
 

3 Utilizing the OC4J Class-Loading Framework

This chapter explains how to use class loading and shared libraries for applications deployed to Oracle Containers for J2EE (OC4J). The explanations include guidelines for using the OC4J class-loading framework, recommendations for avoiding common class-loader problems, and information about class-loading features in Peek OC4J Runtime Inspector (Peek).

The following topics are included:

Class Loading in OC4J

This section contains the following topics:

Overview of Class Loading

The term class loading refers to the process of locating the bytes for a given class name and converting them into a Java class instance. All class instances within a Java Virtual Machine (JVM) start as an array of bytes, structured in the class file format defined by the JVM specification.

Class loading is performed by the JVM during the startup process, and subsequently by class loaders, subclasses of the java.lang.ClassLoader class, which find and load class files at runtime. Class loaders provide an abstraction that enables the JVM to load classes without any knowledge of where the class bytes come from, for both local and remote storage as well as dynamic class generation.

Each class loader works with one or more code sources, root locations from which the class loader searches for classes. Code sources can be defined to represent physical storage of binary class files, Java sources that must first be compiled, or even classes generated on the fly.

Standard class loaders are linked together in a parent-child hierarchy, with each class loader having an associated parent class loader. This hierarchy represents a tree structure, ranging in complexity from simple chains to complex, multibranched trees.

In this hierarchy, a child class loader imports a set of class loaders from its parent loader. In the OC4J context, all J2EE applications running within an OC4J instance are children of the system application. As a result, a class loader created at the application level imports a set of class loaders from the system.root class loader.

Figure 3-1 shows the class-loader hierarchy for a running OC4J instance through Peek. This display is a result of selecting Loaders from the View menu of Peek. See "Peek Utility for Debugging Class Loaders" for detailed information about the Peek utility.

Figure 3-1 Class-Loader Hierarchy

class loading page of the peek utility

Peek Utility for Debugging Class Loaders

Peek OC4J Runtime Inspector enables you to search shared libraries and code sources, view the OC4J class-loader tree, and execute predefined queries to examine various aspects of the OC4J Runtime. Built-in to the default Web application of an OC4J instance, Peek is accessible through the following URIs:

  • OC4J Standalone (oc4j_extended.zip):

    http://localhost:8888/peek/
    
  • Oracle Application Server

    http://localhost:instance_port/j2ee/peek
    

    See "OC4J in an Oracle Application Server Configuration" in the Oracle Containers for J2EE Configuration and Administration Guide for more information on OC4J in Oracle Application Server

To logon to Peek, use the oc4jadmin username and the password that was set during the first initialization of OC4J.

Using the Peek utility, you can perform the following tasks:

  • Search for any code source (JAR, ZIP, or directory) by name or path component. The search string can include wildcard characters and regular expressions. Simply enter the name in the text field and click go.

    Figure 3-2 shows the output from a search for the oc4j.jar code source.

    Figure 3-2 Search for a Code Source in Peek

    a sample code source search in the peek utility
  • Search the contents of all code sources for class or resource names. The search string can include wildcard characters and regular expressions. Simply enter the fully qualified classname in the text field and click go.

    Figure 3-3 shows the output from a search for java.lang.String resource. The output indicates from which code source and class loader the resource was found.

    Figure 3-3 Search for a File in Peek

    The find reference page of the Peek utility
  • View the class-loader tree, as Figure 3-1 shows, and browse its contents:

    • Each loader name and category, and for shared libraries, a description and contact information if available

    • Code sources

    • Loaded classes

    • All classes, with hyperlinks

    • All text-based resources

  • Execute predefined queries to examine various aspects of the OC4J Runtime.

    For example, you can use the loadClass query to attempt to load a class from a specified class loader. Also, you can use the AuditLoader query to validate a class loader (shared library).

  • Link to or bookmark any query run, because all operations are driven through a URL

    For example, you can bookmark a URL like the following one to list any duplicate classes that were loaded into an OC4J instance:

    http://localhost:8888/query?q=DuplicateClasses
    

Class Versioning with Shared Libraries in OC4J

The class-loader hierarchy ensures that a J2EE application deployed into the OC4J instance inherits a set of libraries by default from the default application. A Web module bound to this application, in turn, inherits a set of classes from the application, as well as the classes inherited from the system application, which sits at the root of the application hierarchy in OC4J.

However, this inheritance model is not always desirable, such as when a nondefault version of a library or class is needed by an application or module. The OC4J class-loading infrastructure addresses this problem by enabling class loaders created for an application or module to import a different version of a shared library than the default version imported by the parent class loader. An application or loader can even remove a class loader from the set of inherited class loaders entirely.

Figure 3-4 illustrates the class-loader tree structure in OC4J.

Figure 3-4 The OC4J Class-Loader Tree

Description of Figure 3-4 follows
Description of "Figure 3-4 The OC4J Class-Loader Tree"

  • The jre.bootstrap loader is a proxy for the native bootstrap loader built into the JVM. The native bootstrap loader itself is not directly visible at runtime.

  • The jre.extension loader is a custom replacement for the JRE-supplied "extension" loader.

  • The api loader contains J2EE and OC4J API classes that must be visible to all applications as well as to all OC4J internal classes.

  • The oc4j loader contains OC4J system classes.

  • The system.root loader is created for the OC4J system application.

    Because system is at the root of the application hierarchy, the classes in this loader are inherited by default by all other applications deployed into the OC4J instance.

  • global.root is the class loader created for the default application, which is the default parent of all J2EE applications deployed to the OC4J instance.

  • app-name.root is the root loader for a deployed application.

  • app-name.web.web-mod-name class loaders each contain Web module - classes packaged within a WAR file.

  • app-name.jsp.jsp name loads a compiled JSP implementation class.

The OC4J shared class loaders, oracle.jdbc:10.1.0_2, oracle.jdbc:9.2.0_5, oracle:xml:10_1_02 and xerces:xml:2.6.2, represent shared libraries declared in the OC4J instance. Each shared library definition consists of these items:

  • A shared library name, such as xerces.xml

  • A version number that typically represents the shared library's implementation version, such as 2.6.2

  • One or more code sources, JAR or ZIP files, containing the classes that comprise the library

Class Loaders are created at runtime based on the shared library definitions within the OC4J instance. Class Loaders are registered using a concatenation of the shared library name and the version number; for example, xerces.xml:2.6.2.

See "Installing and Publishing a Shared Library in OC4J" for detailed instructions on creating and installing shared libraries.

The JDBC driver and XML parser classes are loaded by the three deployed applications: While Application 1 follows the default behavior of inheriting the classes contained in the oracle.jdbc:10_1_02 and oracle:xml:10_1_02 shared loaders from its parent, Application 2 and Application 3 each import alternative driver and parser class loaders for their use.

By default, an application inherits the same set of shared libraries present in its parent application, including libraries inherited from the system application. This means, for example, that an application will by default use the Oracle JDBC driver and Oracle XML parser, which are inherited from the system application.

However, using OC4J's class versioning capabilities, you can override an inherited library with a different version, or even remove a library from the list of inherited libraries altogether.

Shared Libraries That Applications Import by Default

The default set of shared libraries imported by all application class loaders within the OC4J instance is specified within the <imported-shared-libraries> element in ORACLE_HOME/j2ee/instance/system-application.xml. This is the configuration file for the system application, an internal component of Oracle Containers for J2EE that sits at the root of the application hierarchy and provides classes and configuration required at OC4J startup. To view the imported shared libraries using peek, use the following URL:

http://localhost:8888/peek/loader/system.root:0.0.0

By default, an application deployed to an OC4J instance will inherit the following Oracle shared libraries:

  • oracle.dms:3.0

  • oracle.jdbc:10.1.0_2

  • oracle.gdk:10.1.0_2

  • oracle.xml:10.1.0_2

  • oracle.xml.security:10.1.3

  • oracle.toplink:10.1.3

  • oracle.persistence:1.0

  • oracle.ws.jaxrpc:1.1

  • oracle.ws.client:10.1.3

  • oracle.cache:10.1.3

  • soap:10.1.3

  • oracle.sqlj:10.1.3

  • oracle.jwsdl:10.1.3

  • global.libraries:1.0

  • global.tag.libraries:1.0

  • oracle.http.client:10.1.3

  • org.jgroups:2.3

Configuring an Application to Import a Nondefault Version of a Shared Library

You can force an application to import a different version of a shared library than the one declared in system-application.xml by creating a shared library with the same name, but assigning a different version number. You will then configure the application to import this shared library.

See the following sections for details:

Example: Importing an Earlier Version of the Oracle JDBC Driver

The following example shows you how to configure an application to use an Oracle 9.2.0_5 JDBC driver, which is an earlier version of the Oracle JDBC driver than the version packaged with OC4J 10g (10.1.3.5.0). This example applies only to thin JDBC drivers and does not apply to the Oracle Call Interface (OCI) drivers.

Step 1: Create the Shared Library in OC4J

You can install a shared library for the 9.2.x JDBC driver using any of the mechanisms described in "Options for Installing and Publishing a Shared Library". This example illustrates how to do this task with Application Server Control.


Note:

To use a JDBC driver that is not packaged with OC4J, you must create a managed data source specifically for use by the application, then configure the application to use it.

This is necessary because the default JDBC drivers and data sources used by applications are imported by the global system application's class loader. Because your application is loading a different driver, it must also load a data source for the driver to use.

See the Oracle Containers for J2EE Services Guide for details on creating and using application-specific managed data sources.


  1. Click Administration>Shared Libraries. Note the default JDBC driver shared library, oracle.jdbc:10.1.0_2.

  2. Click Create on the Shared Libraries page.

  3. Enter the name for the shared library. In this case, you will enter the same name as the existing library, which is oracle.jdbc.

  4. Enter the shared library version, which in this case is 9.2.0_5.

  5. Click Add to upload the library JAR file to the OC4J instance. The following shared library declaration is added to the ORACLE_HOME/j2ee/instance/server.xml file:

    <shared-library name="oracle.jdbc" version="9.2.0_5">
                    <code-source path="ojdbc14.jar"/>
            </shared-library>
    

Step 2: Configure an Application to Use the Shared Library

Once the shared library has been created in OC4J, you can configure an application to use it instead of the default shared library installed with OC4J.

The following example illustrates how to do this at the time the application is deployed with Application Server Control.

  1. Select Applications>Deploy to launch the Application Server Control deployment wizard.

  2. Supply the path to the application in the first page of the wizard.

  3. Specify the application name and supply any context URI mappings in the second page.

  4. Click Configure Class Loading in the third page of the wizard (Deploy: Deployment Settings).

    Both versions of the oracle.jdbc shared library are listed under Import Shared Libraries.

  5. Specify the version number you want to use, 9.2.0_5, in the Maximum Version To Use column.

  6. Deploy the application.

    After the application is deployed, the following entry is in the orion-application.xml deployment descriptor for the application:

    <imported-shared-libraries>
      <import-shared-library name="oracle.jdbc" max-version="9.2.0_05"/>
    </imported-shared-libraries>
    

Example: Configuring an Application to Use a DataDirect JDBC Driver

The Oracle Application Server distribution includes several JDBC drivers to provide connectivity to non-Oracle databases. The following example shows you how to configure an application to use the DataDirect Sybase driver to connect to a Sybase database.

Step 1: Create the Shared Library in OC4J

You can install a shared library for the driver using any of the mechanisms described in "Options for Installing and Publishing a Shared Library". This example will illustrate how to do this task with Application Server Control.

  1. Click Administration>Shared Libraries.

  2. Click Create on the Shared Libraries page.

  3. Enter the name for the shared library; for example, sybase.jdbc.

  4. Enter a version number for the shared library, such as 1.0.

  5. Click Add to upload the library JAR files to the OC4J instance. Note that the YMbase.jar and YMutil.jar files are required to use any of the DataDirect drivers provided with Oracle Application Server.

    • YMsybase.jar

    • YMbase.jar

    • YMutil.jar

    The following shared library declaration is added to the ORACLE_HOME/j2ee/instance/server.xml file:

    <shared-library name="sybase.jdbc" version="1.0">
                    <code-source path="YMbase.jar"/>
                    <code-source path="YMutil.jar"/>
                    <code-source path="YMsybase.jar"/>
            </shared-library>
    

Step 2: Configure an Application to Use the Shared Library

Once the shared library has been created in OC4J, you can configure an application to use it instead of the default shared library installed with OC4J.

The following example illustrates how to do this task at the time the application is deployed with Application Server Control.

  1. Select Applications and then Deploy to launch the Application Server Control deployment wizard.

  2. Supply the path to the application in the first page of the wizard.

  3. Specify the application name and supply any context URI mappings in the second page.

  4. Click Configure Class Loading in the third page of the wizard (Deploy: Deployment Settings).

  5. Check the Import checkbox for the sybase.jdbc shared library. Optionally specify 1.0 as the maximum version to use.

  6. Deploy the application.

    After the application is deployed, the following entry is in the orion-application.xml deployment descriptor for the application:

    <imported-shared-libraries>
      <import-shared-library name="sybase.jdbc" max-version="1.0"/>
    </imported-shared-libraries>
    

Removing or Replacing an Oracle Shared Library Imported by Default

The shared library framework also allows a shared library to be removed from the set of shared libraries inherited by an application from its parent, and optionally allows a different shared library to be imported in its place.

You can remove a shared library that an application inherits by default with a <remove-inherited> subelement within an <imported-shared-libraries> element in an orion-application.xml deployment descriptor for the application. The name of the library to remove is specified as the value for the name attribute.

For example, the following entry in orion-application.xml will prevent the application from importing the Oracle TopLink shared library:

<orion-application>
  <imported-shared-libraries>
    <remove-inherited name="oracle.toplink"/>
  </imported-shared-libraries>
</orion-application>

For complete examples, see the following subsections.

Example: Replacing the Oracle XML Parser with the Xerces Parser

The following example illustrates how to remove the Oracle XML parser from the default set of shared libraries inherited from the system application with Application Server Control. It will also force the application to use the Xerces XML parser in its place.

Step 1: Create the Shared Library in OC4J

You can install a shared library for the Xerces parser using any of the mechanisms described in "Options for Installing and Publishing a Shared Library". This example illustrates how to do this task with Application Server Control.

  1. Click Administration>Shared Libraries.

  2. Click Create on the Shared Libraries page.

  3. Enter the name for the shared library. In this case, you will enter xerces.xml.

  4. Enter the shared library version, which in this case is 2.5.0.

  5. Click Add to upload the library JAR files to the OC4J instance. Upload the following Apache libraries:

    • xercesImpl.jar

    • xml-apis.jar

    The following shared library declaration is added to the ORACLE_HOME/j2ee/instance/server.xml file:

    <shared-library name="xerces.mxl" version="2.5.0">
                    <code-source path="xercesImpl.jar"/>
      <code-source path="xml-apis.jar"/>
            </shared-library>
    

Step 2: Configure an Application to Use the Shared Library

Once the shared library has been created in OC4J, you can configure an application to use the Xerces parser instead of the default parser installed with OC4J.

The following example illustrates how to do this at the time the application is deployed with Application Server Control.

  1. Select Applications>Deploy to launch the Application Server Control deployment wizard.

  2. Supply the path to the application in the first page of the wizard.

  3. Specify the application name and supply any context URI mappings in the second page.

  4. Click Configure Class Loading in the third page of the wizard (Deploy: Deployment Settings).

  5. Check the Import checkbox for the xerces.xml shared library. Optionally specify 2.5.0 as the maximum version to use.

  6. To explicitly remove the Oracle parser, un-check the Import checkbox for the oracle.xml shared library to remove it from the list of shared libraries inherited by the application.

  7. Optionally click the Save Deployment Plan button, and save the plan for re-use.

  8. Deploy the application. After the application is deployed, note the following entry in the application's orion-application.xml file:

    <orion-application>
      <imported-shared-libraries>
        <remove-inherited name="oracle.xml"/>
        <import-shared-library name="xerces.xml" max-version="2.5.0"/>
      </imported-shared-libraries>
    </orion-application>
    

Example: Removing an Oracle Shared Library at Deployment Time

The following example illustrates how to remove the Oracle TopLink shared library at the time the application is deployed with Application Server Control.

  1. Select Applications>Deploy to launch the Application Server Control deployment wizard.

  2. Supply the path to the application in the first page of the wizard.

  3. Specify the application name and supply any context URI mappings in the second page.

  4. Click Configure Class Loading in the third page of the wizard (Deploy: Deployment Settings).

  5. Uncheck the Import checkbox for the oracle.toplink shared library to remove it from the list of shared libraries inherited by the application.

  6. Optionally click the Save Deployment Plan button, and save the plan for re-use.

  7. Deploy the application. After the application is deployed, note the following entry in the application's orion-application.xml file:

    <orion-application>
      <imported-shared-libraries>
        <remove-inherited name="oracle.toplink"/>
      </imported-shared-libraries>
    </orion-application>
    

Using a Packaged JAR Instead of an Oracle Shared Library

The class-loading infrastructure enables you to package an XML parser or JDBC driver as a JAR with your application and then force the application to use it instead of the Oracle XML parser or JDBC driver installed with OC4J, without having to declare the JAR as a shared library within OC4J.

Configuring an Application to Use Its Own Shared Library

In this case, you will specify the default inherited Oracle library in the <remove-inherited> tag in orion-application.xml, which is then packaged with the JAR in the application's EAR file. After deployment to OC4J, the application will not import the default library installed with OC4J, causing the application's class loader to find and load your packaged library instead.

The following notation in orion-application.xml will prevent the application's class loader from importing the Oracle XML parser:

<imported-shared-libraries>
  <remove-inherited name="oracle.xml"/>
</imported-shared-libraries>

In the case of Web applications, you can specify that classes bundled within the application's WAR file be used through a notation in the application's orion-web.xml descriptor file.

First, add or uncomment the <web-app-class-loader> element in this file. Next, set the search-local-classes-first attribute to true in this element, which causes the class loader to find and load any libraries packaged in the WAR and to use these libraries rather than the corresponding libraries packaged with OC4J.

For information about how you can do this at deployment time with Application Server Control, see "Specifying search-local-classes-first at Deployment Time".

The entry in orion-web.xml looks like this:

<orion-web-app ...>
  ...
  <web-app-class-loader search-local-classes-first="true"
   include-war-manifest-class-path="true" />
  ...
</orion-web-app>

This approach is not a guaranteed solution; if an application further up the hierarchy imports a shared library that includes the same classes, a collision is likely, and such collisions are difficult to debug. Ideally, you should use the shared library mechanism documented in this chapter to ensure that your Web applications use the correct library.

Specifying search-local-classes-first at Deployment Time

The following example illustrates how to set the search-local-classes-first attribute in the orion-web.xml file generated for the Web module at deployment time, with Application Server Control.

  1. Select Applications>Deploy to launch the Application Server Control deployment wizard.

  2. Supply the path to the application in the first page of the wizard.

  3. Specify the application name and supply any context URI mappings in the second page.

  4. Click Configure Class Loading in the third page of the wizard (Deploy: Deployment Settings).

  5. Under Configure Web Module Class Loaders, check the Search Local Classes First checkbox next to the name of the Web module containing the local JAR file to use.

  6. Optionally click the Save Deployment Plan button, and save the plan for reuse.

Installing and Publishing a Shared Library in OC4J

Creating a shared library within an OC4J instance is essentially a two-step process. First, the binaries composing the shared library must be installed in the appropriate directory within OC4J. The shared library must then be declared in the OC4J server configuration file (server.xml), essentially "publishing" it within the OC4J instance.

This section includes the following topics:

When You Should Use a Shared Library

Typically, applications deployed to OC4J will use the set of shared libraries packaged with OC4J, which are inherited from the system application. However, there are scenarios in which replacing or removing a library inherited from the application's parent is necessary. Example use cases include:

  • Using a different version of the Oracle JDBC driver than the version packaged with OC4J

  • Replacing the Oracle XML parser packaged with OC4J with a different parser for use by your application

  • Sharing proprietary classes across one or more specific applications, rather than across all applications

  • Making an open source library, such as Struts or the Spring Framework, available to multiple Web applications

Options for Installing and Publishing a Shared Library

OC4J provides several options for installing and publishing shared libraries within one or more OC4J instances. Each of these mechanisms will install the shared library in the ORACLE_HOME/j2ee/instance/shared-lib directory and make the required entry in server.xml.

  • Oracle Enterprise Manager 10g Application Server Control

    This option enables you to install a shared library on a specific OC4J instance through the Administration>Administration Tasks>Shared Libraries pages.

  • The publishSharedLibrary Ant task

    This option enables you to install a shared library on a standalone OC4J server or on a single OC4J instance in an Oracle Application Server environment managed by Oracle Process Manager and Notification Server (OPMN).

  • The -publishSharedLibrary command in admin_client.jar

    This option also enables you to install a shared library on a single OPMN-managed OC4J instance or on a standalone OC4J server.

You can also manually install and publish a shared library within an OC4J instance by following the process described under "How a Shared Library Is Installed and Published in an OC4J Instance".


Note:

If you are using JDK1.4, Oracle Application Server 10.1.3 does not support using the Xalan library shipped with the JDK as a shared library. To use the Xalan library, you have two alternatives:
  • Use JDK 6 or JDK 5.0 (JDK 1.5), in which the embedded Xalan library is supported as a shared library.

  • With JDK1.4, use a standalone distribution of the Xalan library instead of the embedded version.


How a Shared Library Is Installed and Published in an OC4J Instance

Shared libraries are installed in the ORACLE_HOME/j2ee/instance/shared-lib directory in OC4J. The process includes creating the correct directory structure within this directory and then copying one or more JAR or ZIP files that compose the library into the directory.

OC4J provides several tools that automate this process. See "Options for Installing and Publishing a Shared Library" for an overview.

To manually install a shared library:

  1. Ensure that the classes are not already present in the OC4J instance by searching for the classes through Peek, which is described in "Peek Utility for Debugging Class Loaders".

    Figure 3-5 shows the results of searching a running OC4J instance in Peek for any classes whose path name contains *acme*.

    Figure 3-5 Class Search with Peek

    searching for a class in Peek
  2. Create the following directory structure:

    ORACLE_HOME/j2ee/instance/shared-lib
      /library_name
        /version
          filename.jar
          filename.zip
          ...
    

    The variables in the directory structure have these values:

    • instance is the name of an OC4J instance, which is home by default in an Oracle Application Server environment and always home on a standalone OC4J server.

    • library_name is a directory named with the name of the shared library; for example, acme.common.

      In cases where common APIs are implemented by multiple vendors, the name should include both the vendor name and the name of the technology; for example, oracle.jdbc or xerces.xml. If the technology is implemented by a single vendor, the technology name alone is sufficient.

    • version is a subdirectory named for the shared library version number; for example, 2.5. This value should ideally reflect the code implementation version.

  3. copy each JAR or ZIP file containing the classes that compose the shared library into the version subdirectory. For example, assume the sample library consists of acme-apis.jar and acmeImpl.jar. Given the preceding examples, the resulting directory structure within the OC4J server would be as follows:

    ORACLE_HOME/j2ee/instance/shared-lib
      /acme.common
        /2.5
          acme-apis.jar
          acmeImpl.jar
    
  4. To create multiple versions of the shared library, install each version's archive files in the version subdirectory, as the following example illustrates:

    ORACLE_HOME/j2ee/instance/shared-lib
      /acme.common
        /2.5
          acme-apis.jar
          acmeImpl.jar
        /3.0
          acme-apis.jar
          acmeImpl.jar
    

After the code sources are installed, the shared library is defined within a <shared-library> element that is added to the ORACLE_HOME/j2ee/instance/server.xml file, which contains the configuration data for the OC4J instance. The <shared-library> element takes the following attributes and subelements:

  • A required name attribute, the value of which must match the name of the shared library directory created within the /shared-lib directory.

  • A required version attribute, the value of which must match the version number that serves as the name of the subdirectory containing the shared library's archive files in the /shared-lib/library_name directory.

  • One or more <code-source> subelements, each containing a path attribute defining the path to a JAR or ZIP file belonging to the library.

    A path can be absolute if it is outside of the /shared-lib directory, or it can be relative to the subdirectory containing the JAR or ZIP files within the /shared-lib/library_name directory. If a path is relative, only the archive file name needs to be supplied as the value for path.

The following example illustrates a shared library definition in the server.xml configuration file for the example shared library. The code source paths are relative to the subdirectory containing the JAR or ZIP files within the /shared-lib/acme.common directory; therefore, only the archive file names are specified as path values.

<shared-library name="acme.common" version="2.5">
  <code-source path="acme-apis.jar">
  <code-source path="acmeImpl.jar"/>
</shared-library>

You can set path="*" to force OC4J to consume all of the archives within the subdirectory. For example:

<shared-library name="acme.common" version="2.5">
  <code-source path="*" />
</shared-library>

Additionally, a shared library can be configured to import one or more other shared libraries. The <shared-library> element can take one or more <import-shared-library> elements, each specifying a shared library to be imported by the shared library being configured. An imported shared library must also be installed and published on the OC4J host.

The following sample code causes the acme.common shared library to import the xyz.log shared library:

<shared-library name="acme.common" version="2.5">
  <import-shared-library name="xyz.log"/>
  <code-source path="acme-apis.jar"/>
  <code-source path="acmeImpl.jar"/>
</shared-library>

When a relative code-source path is encountered at runtime, the full path is constructed by concatenating the shared library directory (/shared-lib), the shared library name, and the version number. For example, the preceding sample entries would resolve to these paths:

ORACLE_HOME/j2ee/instance/shared-lib/acme.common/2.5/acme-apis.jar
ORACLE_HOME/j2ee/instance/shared-lib/acme.common/2.5/acmeImpl.jar

Configuring an Application to Import a Shared Library

Once a shared library is installed, you can configure applications to import it using one of the following options:


Note:

Declaring a dependency using any of these options makes the shared library required by the application. An error will result if the shared library has not already been installed and published within the OC4J instance.

Declaring Dependencies in an Application's OC4J Deployment Descriptor

A dependency can be declared by adding notations in the dependent application's orion-application.xml deployment descriptor.

Dependencies are declared by adding an <imported-shared-libraries> element in the application-specific orion-application.xml configuration file. This element takes one or more <import-shared-library> subelements, each specifying a shared library to import.

The <import-shared-library> element has the following attributes:

  • name: The name of the shared library.

  • min-version and max-version: These are optional attributes that enable you to specify a minimum or maximum version of the library to be specified for inclusion. To use the latest installed version of the library, do not specify a version number.

The following entry in orion-application.xml will import the acme.common:2.5 shared library for use by the application:

<imported-shared-libraries>
  <import-shared-library name="acme.common" max-version="2.6"/>
</imported-shared-libraries>

Declaring Dependencies in an Application's Manifest File

The standard Java extension mechanism, also known as optional packages, can be utilized to declare an application dependency on a JAR or ZIP file within a shared library. This is the standard J2EE mechanism for declaring dependencies on installed libraries.

To use this mechanism, the dependent JAR or ZIP file must be declared as a named extension in its MANIFEST.MF file. This name is specified as the value of the Extension-Name attribute. For example, the following manifest entry defines acme.common as an extension:

Extension-Name: acme.common
Specification-Vendor: Acme, Inc 
Specification-Version: 2.5 
Implementation-Vendor-Id: com.acme 
Implementation-Vendor: Acme, Inc 
Implementation-Version: 2.5 

The application that is dependent on the shared library then declares the dependency in its own manifest file. The following manifest attributes will cause the application to import the acme.common:2.5 shared library. The value of the name-Extension-Name attribute matches the Extension-Name value specified for the JAR or ZIP file's manifest file:

Extension-List: acme
acme-Extension-Name: acme.common
acme-Implementation-Version: 2.5

Version numbers in the Specification-Version and Implementation-Version attributes of a MANIFEST.MF file can have up to eight elements:

n1.n2.n3.n4.n5.n6.n7.n8

The maximum allowed value for an element is 99999999.

For more information on declaring dependencies using manifest files, see the following Web site:

http://java.sun.com/j2se/1.4.2/docs/guide/extensions/versioning.html

Configuring All Deployed Applications to Import a Specific Shared Library

You can ensure that all applications deployed to an OC4J instance use the same version of a shared library by configuring the default application to import it. Because default is the parent of all applications deployed to OC4J, any shared libraries that default imports will also be imported by these applications.

The configuration is managed by adding the XML notations described in "Declaring Dependencies in an Application's OC4J Deployment Descriptor" to the ORACLE_HOME/j2ee/instance/application.xml file, the configuration file for the default application.

The following entry in application.xml will ensure that all deployed applications use version 2.0 of the acme.common shared library:

<imported-shared-libraries>
  <import-shared-library name="acme.common" max-version="2.0"/>
</imported-shared-libraries>

Note that an application will use the version of a shared library imported from the default application—even if the application includes its own version of the shared library. If this is not desirable, you can "remove" the version imported from default using the process described in "Removing or Replacing an Oracle Shared Library Imported by Default".

Sharing Libraries Using the applib Directory

The legacy mechanism for sharing libraries across applications within OC4J, in which JAR or ZIP files to be shared are installed in the ORACLE_HOME/j2ee/instance/applib directory, is still supported in the current release of OC4J. All JAR and ZIP files within this directory will be included in the global.libraries shared library, and will be available to all applications within the OC4J instance.

Support for this legacy functionality will be removed in a future release of OC4J. Oracle recommends that you use the new shared-library mechanism documented in this chapter whenever possible.

Specifying a Library Directory in application.xml

The <library-directory> element of the application.xml file specifies either a relative or absolute path or URL to a directory or a JAR or ZIP archive to add as a library path for this OC4J instance. Directories are scanned for archives to include at OC4J startup.

If the application.xml file for an application has the version="5" attribute set (Java EE 5 application), the <library-directory> element of the EAR file's deployment descriptor can contain the name of a library directory through with application components can share libraries.

<application version="5">
    <library-directory>app2lib</library-directory>
    <module>
        <ejb>ejb.jar</ejb>
    </module></application>

If a <library-directory> element is not specified, or if the EAR file does not contain a deployment descriptor, the directory named lib is used.

You can use an empty <library-directory> element to specify that there is no library directory. For example:

<application version="5">
    <library-directory></library-directory>
    <module>
        <ejb>ejb.jar</ejb>
    </module></application>

The <library-directory> element provides a standard mechanism to define class path dependencies, as defined in the Java EE 5 specification. In OC4j 10g (10.1.3.5.0), all files in a library directory with a .jar extension (but not in subdirectories) are available to all components packaged in the EAR file except application clients. Libraries in these JAR files can reference other libraries, either bundled with the application or installed separately.

OC4j 10g (10.1.3.5.0) also supports the <library-directory> element in J2EE 1.4 applications, with the following caveats:

The proprietary <library> element in the orion-application.xml file provides the same functionality as <library-directory>.

Applications that use the <library-directory> element or Java EE 5 applications that do not use an empty <library-directory> element will have an extra deployment step that iterates over files in the library directory and adds them to the class path.

Using Best Practices for Class Loading

This section provides guidelines for avoiding class-loading issues.

Declare Class Dependencies

Make dependencies explicit in the application's MANIFEST.MF file or orion-application.xml file. Hidden or unknown dependencies will be left behind when you move your application to another environment.

Group Dependencies Together

Ensure that all dependencies are visible at the same level or above. If you must move a library, make sure all dependencies are still visible. Ensure that application resources, dependent third-party libraries, and other enterprise modules are packaged in a self-contained manner.

Share Rather Than Duplicate Libraries

Avoid duplicating libraries, which increases both the disk and memory footprints and can lead to version problems.

Minimize Library Visibility

Dependency libraries should be placed at the lowest visibility level that satisfies all dependencies.

Keep Your Configurations Portable

Choose configuration options in the following order:

  1. Standard J2EE options

  2. Options that can be expressed within your EAR file

  3. Server-level options

  4. J2SE extension options

Be Sure to Use the Correct Class Loader

If you use reflection by calling Class.forName(), always explicitly pass the class loader returned by Thread.currentThread().getContextClassLoader. If you are loading a properties file, use this code:

Thread.currentThread().getContextClassLoader().getResourceAsStream()

Calling Class.forName() is preferred over ClassLoader.loadClass() due to a slight performance benefit and accurate cache entries.

If you intend to run static initializers while calling Class.forName(), use true as a Boolean flag, as in Example 3-1. If you do not want to run static initializers while calling Class.forName(), due to performance or security reasons, use false in the method signature.

Example 3-1 Class.forName Call While Running Static Initializers

Class.forName(name, true, loader);

Troubleshooting Class-Loading Problems in OC4J

OC4J provides configuration options and built-in queries to help you troubleshoot and resolve class-loading problems.

Most class-loading errors in Java are related to visibility, either not enough or, more rarely, too much. Visibility in this case refers to the set of classes and resources that are available on the class path, which is the search path across a set of loaders and the code sources they contain (for example, JAR files, ZIP files, and directories).

In Java SE, the class path is usually thought of as the list of code sources specified on the command line or in the manifest file for the main JAR file. These code sources are all deployed in a single loader, usually referred to as the system loader. This loader is in turn wired up to two other loaders: the JRE extensions loader (normally for any JAR files in the jre/lib/ext directory) and the JRE bootstrap loader (containing rt.jar and so on).

The idea that there is a class path is often misleading. For each class lookup, the search begins at a specific loader, and (normally) can visit only loaders above the class in the class-loader hierarchy. This means that a search starting at the extensions loader would have a very different class path than one starting at the system loader.

In Java EE, the situation is substantially more complicated, as multiple class loaders are required in place of the single system loader. Each deployed application has at least one loader, separate from all other applications, so each application has a distinct class path. There are frequently different class paths even within a single application, as each Web module is deployed in a separate loader.

You can easily see this by making the following call from within different modules:

System.getProperty("java.class.path");

OC4J ensures that the correct class path is returned for the calling module.

There are many configuration options that affect class visibility for applications. Table 3-1 lists the most common options within OC4J. Given the possible combinations of loaders and code sources in a J2EE environment, it is easy to see how visibility errors can arise. Often, a simple configuration change is all that is required to eliminate the problem, but understanding what change to make can be tricky.

Table 3-1 Configuration Options That Affect Class Visibility

Class Loader Configuration Option

Configured shared library

<code-source> in server.xml


<import-shared-library> in server.xml

app-name.root

<import-shared-library> in orion-application.xml


<library> JAR files, ZIP files, and directories in orion-application.xml


<library-directory> JAR files, ZIP files, and directories in application.xml


<ejb> JAR files and ZIP files in orion-application.xml


RAR file: all JAR and ZIP files at the root.


RAR file: <native-library> directory paths


Manifest class path of preceding JAR and ZIP files

app-name.web.web-mod-name

WAR file: Manifest class path


WAR file: WEB-INF/ classes


WAR file: WEB-INF/lib/ all JAR and ZIP files


<classpath> to all JAR files, ZIP files, and directories in orion-web.xml


Manifest class path of preceding JAR files


search-local-classes-first attribute in orion-web.xml


Shared libraries are inherited from the application root.


OC4J provides a number of built-in queries that you can run to troubleshoot class-loading problems. Figure 3-6 shows a list of these queries in Peek.

Figure 3-6 Queries for Troubleshooting Class-Loading Problems

available queries

Specifying a Built-In Query

You can use any of the following tools to specify the built-in queries for troubleshooting:

Specifying a Query in Peek

In the Peek command-line window, you can enter a query to get information about a running OC4J instance or to show the arguments of a query.

To specify a query in Peek, enter the query name with any argument in the Peek command-line window.

Figure 3-7 shows a query for the ascontrol.web.ascontrol.jsp33119438:0.0.0 loader. The figure has been truncated, because the list that is returned is large.

Figure 3-7 Peek Display of ClassPath Query Arguments

class path query in Peek

You can also display the arguments of a query by clicking its name in the list of queries, which Figure 3-6 shows.

Specifying a Query in a Startup Property

You can specify a query in the oc4j.start.query system property, which you can set in the asctl command line for an OC4J instance or in the oc4j.jar command line for standalone OC4J.

Query results are written to the file specified as the value of the class.load.log.file property or if no file is specified, to the console (System.out). The next time OC4J starts or restarts, it executes the query.

For more information about the class.load.log.file property, see "Setting Class-Loader Log Levels".

To specify a query in a startup property for standalone OC4J:

  1. Specify the query name in the oc4j.start.query, system property, prefaced by "-D"

    The characters "-D" must preface each system property on the command line. The syntax for specifying a query on the oc4j.jar command line follows:

    java -Doc4j.start.query=queryName(arg0[,arg1] . . .) -jar oc4j.jar
    
  2. To pass arguments to the query, append (arg0[,arg1] . . .) to the query name. Enclose the arguments in parentheses, and use a comma to separate multiple arguments.


    Note:

    For some Linux or UNIX shells, the property value string (everything after the = symbol) will need to be enclosed in quotation marks.

    For example, the DuplicateCodeSources query can be invoked with a -digest argument as follows:

    java -Doc4j.start.query=DuplicateCodeSources(-digest) -jar oc4j.jar
    
  3. To specify multiple queries in a startup parameter, separate them with the + character:

    -Doc4j.start.query=DuplicateCodeSources(-digest)+UnusedCodeSources
    

Specifying Queries at Runtime Through the ClassLoading MBean

Queries can be executed on a running OC4J instance by calling the executeQuery operation on the ClassLoading MBean.

This MBean is accessible through the Web-based Application Server Control interface. See the Oracle Containers for J2EE Configuration and Administration Guide for details on accessing and using the MBeans packaged with OC4J.

To specify queries at runtime through the ClassLoading MBean:

  1. Click the Administration link in Application Server Control.

  2. Click System MBean Browser.

  3. Expand the ClassLoading node in the navigation pane, then select the singleton MBean instance.

  4. Click the Operations tab in the right-hand pane, then click the executeQuery operation.


    Note:

    Two versions of the executeQuery operation are exposed. Click the version that takes two parameters. (The queryClassData parameter cannot be set through the System MBean Browser.)

  5. Enter the name of the query you want to execute as the value for queryClassName. For example, LoaderTree.

  6. Click the queryArguments icon, then add a new row for each argument you want to specify. Do NOT enclose arguments in parentheses; these are added automatically when the operation is invoked. Click OK when finished specifying arguments.

  7. Click the Invoke button to call the operation.

Auditing Class Loaders

You can use the AuditLoader query to audit one or more of the class loaders available in an OC4J instance by performing diagnostics on their contents. This query enables you to specify the level of audit output and to include JRE classes in the audit.

The output from AuditLoader includes information about errors. If you are adding a new shared library, you should try to remove all errors reported for the new library.

How to Audit Class Loaders with Peek

In Peek you can audit class loaders by entering AuditLoader in the command-line window and specifying the class loaders, optionally followed by additional arguments. Table 3-2 describes the arguments.

To audit class loaders with Peek:

  1. In the list of queries on the initial Peek screen, click AuditLoader.

    Peek places the query name in the command-line window and displays the query arguments.

  2. If you want to specify one or more class loaders to audit, select each class loader from the list under -- loaderName --.

    Peek places each name you select in the command line after AuditLoader.

    Alternatively, you can type the list of class loaders, separating each name from the next with a space.

  3. If you want to audit all class loaders available in the OC4J instance, type * after AuditLoader.

    If you specify AuditLoader * immediately after another AuditLoader query, Peek uses the arguments from the preceding query.

  4. Click go or press the Enter key.

    Peek displays the results of the query.

  5. If you want to run the same query later, save the URL for reuse.

  6. If you are adding a new shared library, try to remove all errors reported in the AuditLoader results for that library and then rerun the query to verify that the errors are gone.

For example, to audit the oracle.jdbc loader with detailed output, you would specify the query as follows:

AuditLoader oracle.jdbc:10.1.0_2 -verbose

Figure 3-8 shows part of the output from an execution of this query. The figure has been truncated, because the list that is returned is large.

Figure 3-8 AuditLoader Query

an audit query from the Peek utility

Note:

it is possible to audit all loaders; however, the system may run out of memory if the user tries to Audit all loaders. Users may specify * to audit all shared loaders (try -XX:MaxPermSize=512m).

What Happens When You Audit Class Loaders

Output from the AuditLoader query can include the following diagnostic information for each class loader:

  • Class loaders that import the class loader being audited

  • Whether or not there is a default import

  • Imported class loaders

  • Member classes

  • Member packages

  • External class dependencies

  • External package dependencies

  • External loader dependencies

  • Notes about the class loader, such other class loaders it uses

  • Warnings

  • Duplicate classes

  • Errors

  • Suggestions for resolving warnings and errors

What You May Need to Know About AuditLoader

The AuditLoader query has the following arguments:

loaderName [loaderName] . . . | * [-verbose] [-includeJREClasses]

Table 3-2 describes these arguments.

Table 3-2 AuditLoader Query Arguments

Argument Description

loaderName

Specifies the name of a class loader to audit.

To audit all shared class loaders, specify an asterisk (*) for loaderName.

*


Specifies the audit of all class loaders in the OC4J instance.

-verbose

Optional. Specifies detailed output.

-includeJREClasses

Optional. Specifies the inclusion of JRE classes in the output.


Finding Classes That Call a Method

The Callers query reports all classes that call the specified method or methods. You can limit the query by specifying the name of a class loader.

How to Find Classes That Call a Method with the Callers Query

For example, to find all classes that call System.currentTimeMillis(), you could execute this query:

-Doc4j.start.query=Callers(java.lang.System.currentTimeMillis()long)

The next example will find the same method in classes visible from the MyApp.root class loader:

-Doc4j.start.query=Callers(-MyApp.root,java.lang.System.currentTimeMillis()long)

To find calls to either version of the overloaded Class.forName() method, pass in both method signatures as arguments:

-Doc4j.start.query=Callers(java.lang.Class.forName(java.lang.
String)java.lang.Class,java.lang.Class.forName(java.lang.String;boolean;java.lang.
ClassLoader)java.lang.Class)

You can include init in the signature argument to specify a constructor:

-Doc4j.start.query=Callers(java.util.Date.init())

What You May Need to Know About Callers

The Callers query has the following arguments:

[-loaderName,]signature . . .

Table 3-3 describes these arguments.

Table 3-3 Callers Query Arguments

Argument Description

-loaderName

Optional. If specified, all classes visible from the named class loader will be checked for the specified methods.

If not specified, all classes visible to all class loaders down the tree from the api class loader, the default parent of all application-specific class loaders, are checked.

signature

A method to check for.

You can specify multiple methods, each as a separate argument.

The syntax follows:

class-type.method-name([parameter-type[;parameter-type]...])return-type

Separate multiple parameter types using semicolons (;). Types must be either fully qualified class names or primitive names. For void return types, you can omit return-type.


Monitoring Metrics for Class Loaders

The ClassLoadMetrics query reports metrics for one or more specified class loaders or for all class loaders if none is specified.

How to Monitor Metrics for Class Loaders with the ClassLoadMetrics Query

For example:

-Doc4j.start.query=ClassLoadMetrics(MyApp.root,MyOtherApp.root)

What You May Need to Know About ClassLoadMetrics

The ClassLoadMetrics query has the following arguments:

[-verbose] [loaderName] ...

Note:

The verbose (multiline) output of the PolicyClassLoader.toString() method is turned off by default in OC4J. Only the loader name and version are returned.

You can enable verbose output by setting either of these system properties:

  • -Dclass.load.log=any value

  • -Dverbose.loader.tostring=true


Table 3-4 describes these arguments.

Table 3-4 ClassLoadMetrics Query Arguments

Argument Description

-verbose

Optional. Supply to generate detailed metrics.

loaderName

Optional. The name of a class loader for which to report metrics.


Listing Code Sources in Use

The ClassPath query lists the code sources in use.

The ClassPath query has the following arguments:

[-list] [loaderName]

Table 3-5 describes these arguments.

Table 3-5 ClassPath Query Arguments

Argument Description

-list

Optional. Include to generate a line-separated, numbered list of code sources.

loaderName

Optional. If specified, the class loader is used as the starting point from which the class path is computed. Otherwise, the class path defaults to the internal class loader that loads all OC4J system classes.


Determining the Dependencies of a Class

The Dependencies query reports all dependencies of the specified class.

The Dependencies query has the following arguments:

className [loaderName] [-r]

Table 3-6 describes these arguments.

Table 3-6 Dependencies Query Arguments

Argument Description

className

The fully qualified name of the class to report dependencies for.

loaderName

Optional. If specified, the class loader is used as the starting point from which dependencies are determined. Otherwise, the internal class loader that loads all OC4J system classes is used.

-r

Optional. Set to search classes recursively. The use of this parameter can cause long execution times.


Determining Dependent Classes

The Depends query reports on all classes that are dependent on the specified class.

The Depends query has the following arguments:

[-loaderName] className 

Table 3-7 describes these arguments.

Table 3-7 Depends Query Arguments

Argument Description

-loaderName

Optional. If specified, all classes visible to the named class loader will be checked. Otherwise, all classes visible to all class loaders from the api class loader downwards are checked.

className

The fully qualified name of the class to check for dependencies. To specify an entire package, use an asterisk (*) as the leaf name.


Finding Duplicate Classes

The DuplicateClasses query reports the existence of classes and resources with the same name in different code sources.

The DuplicateClasses query has the following arguments:

[[-loaderName] [-systemCodeSources]

Table 3-8 describes these arguments.

Table 3-8 DuplicateClasses Query Arguments

Argument Description

-loaderName

Optional. If specified, the named class loader is used as the starting point for the code-source search. Otherwise, all classes visible to all class loaders from the api class loader downwards are checked.

-systemCodeSources

Optional. If specified, includes system code sources in the search.


Finding Duplicate Code Sources

The DuplicateCodeSources query reports code sources that have the same name or have more than one subscriber.

The DuplicateCodeSources query has the following argument:

[-digest]

Table 3-9 describes this argument.

Table 3-9 DuplicateCodeSources Query Argument

Argument Description

-digest

Optional. If specified, bit-wise comparisons of code sources will be performed.


Exiting a Query Process

The Exit query exits the process and shuts down OC4J, if it is running. This is useful if you only want to execute a query without leaving the OC4J server running. For example:

-Doc4j.start.query=LoaderTree+Exit

The Exit query has the following argument:

[-force]

Table 3-10 describes this argument.

Table 3-10 Exit Query Argument

Argument Description

-force

Optional. Forces a System.exit() call instead of a normal shutdown.


Finding a Resource in Code Sources

The FindResource query reports the code sources that contain a specified resource. The code sources are identified by either class name or resource path.

For a simple wildcard search, you can use a leading or trailing asterisk (* )

To indicate that the argument should be treated as a regular expression, you can use a leading tilde (~ )

How to Use the FindResource Query in Peek

In Peek, you can use FindResource to display any code sources that contains a resource.

Figure 3-9 FindResource Query

Find resource query in the Peek utility

How to Find a Resource with No Package

The resourcePath argument must be passed to search for a class with no package. For example, to find class foo, the query would be like this:

-Doc4j.start.query=FindResource(Foo.class)

To search for a resource with no package (/), in which the resource name contains a period (.), you need to use a leading asterisk. For example, you could use the following query to find the myconfig.xml file at the root of a code source:

-Doc4j.start.query=FindResource(*myconfig.xml)

What You May Need to Know About FindResource

The FindResource query has the following arguments:

[[-list] resourcePath|className

Table 3-11 describes these arguments.

Table 3-11 FindResource Query Arguments

Argument Description

-list

Optional. Can be used with wildcard or regular expressions to list all matching resources.

resourcePath

Required if className is not supplied. The fully qualified path to the resource.

className

Required if resourcePath is not supplied. The fully qualified class name of the resource to search for.


Getting Resources Used by a Class Loader

The GetResource query calls getResource() or getResources() on a specified loader and reports the results.

The GetResource query has the following arguments:

resourcePath [loaderName] [-all]

Table 3-12 describes these arguments.

Table 3-12 GetResource Query Arguments

Argument Description

resourcePath

Optional. The fully qualified path to the resource.

loaderName

Optional. If specified, the named class loader is used as the starting point for the resource search. Otherwise, all classes visible to all class loaders from the api class loader downwards are checked.

-all

Optional. If this argument is specified, the query uses getResources(). Otherwise, it uses getResource().


Monitoring HTTP Sessions for Deployed Applications

The HttpSessions query reports a summary of active HTTP sessions for deployed applications.

The HttpSessions query has the following argument:

[details]

Table 3-13 describes this argument.

Table 3-13 HttpSessions Query Argument

Argument Description

details

Optional. If specified, lists details of each HTTP session.


Detecting Class-Loader Leaks

The LeakedLoaders query controls detection of class-loader leaks and lists results.

The LeakedLoaders query has the following arguments:

[activate|list|deactivate]

Table 3-14 describes these arguments.

Table 3-14 LeakedLoaders Query Arguments

Argument Description

activate

Optional. If specified, activates detection of class-loader leaks.

list

Optional. If specified, lists results of class-loader leak detection.

deactivate

Optional. If specified, deactivates detection of class-loader leaks.


Listing Classes Available from a Class Loader

The ListClasses query lists all classes available from a given class loader.

How to List Classes Available from a Class Loader

You can use the ListClasses query as a startup option in the pcscomponent.xml file for an OC4J instance or in the command line to start standalone OC4J, as follows:

java -Doc4j.start.query=ListClasses:loaderName -jar oc4j.jar

For more information about using OC4J startup options, see "Starting, Restarting, and Stopping OC4J Instances" in Oracle Containers for J2EE Configuration and Administration Guide.

Example 3-2 lists the classes in the apache.commons.logging:1.0.4 loader.

Example 3-2 ListClasses Query Output

ListClasses apache.commons.logging:1.0.4

org.apache.commons.logging.Log
org.apache.commons.logging.LogConfigurationException
org.apache.commons.logging.LogFactory
org.apache.commons.logging.LogFactory$1
org.apache.commons.logging.LogFactory$2
org.apache.commons.logging.LogFactory$3
org.apache.commons.logging.LogSource
org.apache.commons.logging.impl.AvalonLogger
org.apache.commons.logging.impl.Jdk14Logger
org.apache.commons.logging.impl.Log4JCategoryLog
org.apache.commons.logging.impl.Log4JLogger
org.apache.commons.logging.impl.Log4jFactory
org.apache.commons.logging.impl.LogFactoryImpl
org.apache.commons.logging.impl.LogFactoryImpl$1
org.apache.commons.logging.impl.LogKitLogger
org.apache.commons.logging.impl.NoOpLog
org.apache.commons.logging.impl.SimpleLog
org.apache.commons.logging.impl.SimpleLog$1

What You May Need to Know About ListClasses

The ListClasses query has the following argument:

loaderName

Table 3-15 describes this argument.

Table 3-15 ListClasses Query Argument

Argument Description

loaderName

The name of the class loader for which to list classes.


Listing Queries

The ListQueries query lists all of the available queries in OC4J, by oracle.oc4j.query.Query subclass name.

How to List Queries

You can use the ListQueries query as a startup option in the pcscomponent.xml file for an OC4J instance or in the command line to start standalone OC4J, as follows:

java  -Dstart.query="ListQueries(-l)"  -jar oc4j.jar

For more information about using OC4J startup options, see "Starting, Restarting, and Stopping OC4J Instances" in Oracle Containers for J2EE Configuration and Administration Guide.

What You May Need to Know About ListQueries

The ListQueries query has the following arguments:

[[-l] [queryclass] ...

Table 3-16 describes these arguments.

Table 3-16 ListQueries Query Arguments

Argument Description

-l

Optional. If specified, lists full descriptions.

queryclass

Optional. If specified, lists each query with a single-line description. Pass one or more query class names to list only those queries.


Loading a Class

You can use the loadClass query to perform a class-loading test run. This query attempts to load a specified class using the specified class loader, or using the internal class loader if none is specified, and reports the result.

The loadClass query is useful for troubleshooting a ClassNotFoundException error. You can use the query to load classes from different initial loaders and get reports on the results.

How to Use the loadClass Query in Peek

In Peek, you can use the loadClass query to load a class into an OC4J instance and view a report on the result.

To use the loadClass Query in Peek:

  1. In a Web browser, go to the /peek/ context root:

    http://localhost:8888/peek/
    
  2. Type the loadClass query with the name of the class you want to load and any optional parameters (see Table 3-17).

  3. Click go or press Enter.

What Happens When You Use the loadClass Query in Peek

Peek loads the specified class and then displays a report with the class name, defining class loader, and code source from which the class was loaded. Figure 3-10 shows a loadClass report.

Figure 3-10 loadClass Query

load class query in peek

What You May Need to Know About loadClass

The loadClass query has the following arguments:

[className [ loaderName] [-forName] [-depends] [-r] [-sort] 

Table 3-17 describes these arguments.

Table 3-17 LoadClass Query Arguments

Argument Description

className

Required. The fully qualified name of the class to report on.

loaderName

Optional. If specified, attempts to load the class using this class loader are reported. If not specified, the internal class loader is used by default.

-forName

Optional. The class-loader method to record attempts for. If not specified, loader.loadClass() is used by default.

-depends

Optional. Specify to force the class loader to load and report on all dependencies of the specified class.

-r

Optional. Specify to load all dependencies recursively. Note that recursion does not include classes in java.* packages.

-sort

Optional. Include to sort the list of dependent classes by class name.


Listing Loaded Classes

The LoadedClasses query lists the names of all loaded classes (if available) in an OC4J instance.

How to Use the LoadedClasses Query in Peek

in Peek you can specify the LoadedClasses query in the command-line window to list loaded classes.

To Use the LoadedClasses Query in Peek:

Figure 3-11 shows the output from a LoadedClasses query.

Figure 3-11 LoadedClasses Query in Peek

load classes query in peek

What You May Need to Know About LoadedClasses

The LoadedClasses query has no arguments.

Listing the Contents of a Class-Loader Tree

The LoaderTree query reports the contents of the class-loader tree for the specified root class loader, or for the JRE bootstrap class loader if none specified. By default, only the names of the class loaders within the tree are reported.

This query is useful if you want to focus on a specific part of the class-loader tree, such as from the root of a specific application downwards. Peek can also be used to list the contents of a class-loader tree. See "Viewing a Class-Loader Tree with Peek" later in this section.

How to List the Contents of a Class-Loader Tree with the LoaderTree Query

For example:

-Doc4j.start.query=LoaderTree(MyApp.root)

To retrieve the entire class-loader tree, do not include a root class-loader name:

-Doc4j.start.query=LoaderTree

What You May Need to Know About LoaderTree

The LoaderTree query has the following arguments:

[[rootLoaderName] [-verbose]

Table 3-18 describes these arguments.

Table 3-18 LoaderTree Query Arguments

Argument Description

rootLoaderName

Optional. The root class-loader name. If not specified, reports the contents of the JRE bootstrap class-loader tree.

-verbose

Optional. Specify to output detailed information. If not specified, only the names of the class loaders within the tree are reported.


Viewing a Class-Loader Tree with Peek

Peek can be used to report the contents of a class loader tree. In addition, Peek can be used to "drill-down" all the way to a specific class within a code source and even see a decompiled stub of the class. The following example demonstrates how to use Peek to view a class-loader tree and also demonstrates how to view a stub for a specific class.

To query a class-loader tree with peek:

  1. From the Peek tool, mouse-over View and select Loaders. The Class-Loader tree displays as shown below. The figure has been truncated, because the list that is returned is large.

    class-loader tree
  2. From the tree, select the oc4j:10.1.3 class-loader link. A report of all imported shared libraries, code sources, and classes displays for the class-loader as shown below. The figure has been truncated, because the list that is returned is large.

    a specific class-loader report in Peek
  3. From the report, click the ${oracle.home}/j2ee/home/oc4j.jar code source link to view all the classes within the JAR. A report of all classes displays as shown below:

    a Peek report of all classes in the jar
  4. From the report, click a class link to see a decompiled stub of the class. For example, the following stub displays when you click the oracle/oc4j/loader/boot/BootStrap.class link:

    a decompiled class in Peek

Listing Packages in Code Sources

The Packages query lists the package names contained within one or more code sources.

The Packages query has the following arguments:

[loaderName | codeSourcePath]

Table 3-19 describes these arguments.

Table 3-19 Packages Query Arguments

Argument Description

loaderName

Optional. If specified, only code sources within that class loader are searched.

codeSourcePath

Optional. If specified, searches the code source path. Otherwise, searches all available code sources.


Monitoring Replication Statistics

The SessionReplicationStats query retrieves statistics for replicated HTTP and EJB sessions for a given application.

The SessionReplicationStats query has the following argument:

[application name]

Table 3-20 describes this argument.

Table 3-20 SharedLibraries Query Argument

Argument Description

application name

Optional. The name of an application that is configured for session replication.


Listing Installed Shared Libraries and Their Class Loaders

The SharedLibraries query lists all installed shared libraries and the class loaders that import the libraries.

The SharedLibraries query has the following argument:

[loaderName]

Table 3-21 describes this argument.

Table 3-21 SharedLibraries Query Argument

Argument Description

loaderName

Optional. The name of a class loader. If specified, lists shared libraries imported by the specified class loader. Otherwise, the shared libraries imported by all class-loader instances are listed.


Listing and Setting System Properties

The SystemProperties query lists or sets system properties.

The SystemProperties query has the following argument:

[key=value] ...

Table 3-22 describes this argument.

Table 3-22 SystemProperties Query Argument

Argument Description

key=value

Optional. The name and value of a system property. If specified, sets the value of the system property. If no key-value pair is specified, lists the current values of system properties.


Figure 3-12 shows a Peek query that returns all system properties that are currently set. The figure has been truncated, because the list that is returned is large.

Figure 3-12 System Property Query from Peek

shows a peek system property query

Listing Thread-Pool Information

The ThreadPools query lists information about thread pools for the current JVM.

The ThreadPools query has the following arguments:

(list [sys|req|cx]|pool [sys|req|cx]|state [sys|req|cx][id])

Table 3-23 describes these arguments.

Table 3-23 ThreadPools Query Arguments

Argument Description

list [sys|req|cx]

If specified, lists all threads in all thread pools or all thread in a specified thread pool.

pool [sys|req|cx]|

If specified, lists all thread pools or details for a specified thread pool.

state [sys|req|cx] [id]

If specified, dumps thread state for all thread pools, for a specified thread pool, or for a specified thread ID.


Listing Thread Information

The Threads query lists thread information for the current JVM. For JDK 1.5, checks for thread deadlocks or gets thread memory usage for the current JVM.

The Threads query has the following arguments:

[list|groups|deadlock|memory]

Table 3-24 describes these arguments.

Table 3-24 Threads Query Arguments

Argument Description

list

Optional. If specified, lists all threads for the current JVM.

groups

Optional. If specified, lists all thread groups for the current JVM.

deadlocks

Optional, for JDK 1.5 only. If specified, checks for thread deadlocks in the current JVM.

memory

Optional, for JDK 1.5 only. If specified, gets thread memory usage for the current JVM.


Finding Unused Code Sources

The UnusedCodeSources query reports code sources that have never retuned any data.

The UnusedCodeSources query has no arguments.

Determining the Uptime for an OC4J Instance

The Uptime query reports the length of time the current OC4J instance has been running.

The Uptime query has no arguments.

Monitoring JVM Statistics

The VMStat query lists statistics information for the current JVM.

The VMStat query has the following arguments:

[jps|pid|mem]

Table 3-25 describes these arguments.

Table 3-25 VMStat Query Arguments

Argument Description

jps

Optional. If specified, Lists the running Java processes.

pid

Optional. If specified, returns the PID of the current JVM.

mem

Optional. If specified, returns memory information about the current JVM.


Resolving Class-Loading Exceptions

Most class-loading errors in J2EE often surface as one of a small set of exceptions. The OC4J class-loading infrastructure provides "annotated" subclasses for each of the following standard class-loading configuration exceptions:

The subclasses enhance the output of the getMessage(), printStackTrace(), and toString() methods with information to help you understand and correct the configuration. Often, this extra information is all that is needed to fix the problem; when it isn't, the logging, tracing, and query features can be used to dig further.

For each error, a diagnostic search may be performed to provide additional information. This search is not restricted by standard loader visibility rules and can visit any loader or code source known to the system. Results are reported as part of the error message.

Under some conditions it would be possible for the loader runtime to act on the results and attempt recovery (such as automatically find and load a missing class). However, this might lead to further problems that would then be more difficult to diagnose.

ClassNotFoundException

This exception can occur during dynamic loading via any method that explicitly loads a class by name, such as Class.forName() or ClassLoader.loadClass(). It indicates that a required class is not visible from the initiating class loader.

How to troubleshoot and resolve

ClassNotFoundException is nearly identical to NoClassDefFoundError. One important difference is that the initial loader can be selected by the calling code, rather than by the JVM, and it is relatively easy to get this wrong.

If the Class.forName(String) method is used, the JRE code will select the initial loader and will always choose the caller's loader. This is rarely correct; it is nearly always better to explicitly pass the thread context loader:

Thread thread = Thread.currentThread();
ClassLoader loader = thread.getContextClassLoader();
Class cls = loader.loadClass(name);

Calling the loader directly is preferred to using the Class.forName() variant:

Class cls = Class.forName(name, true, loader);

While these two calls both try to load from the specified loader, the direct call is easier to understand. It also ensures that tracing works as expected, since some VM implementations of forName() can bypass the loader (only calling the loader if the class is not already cached—the loader always consults the cache itself, so calling the loader directly is safe and efficient).

The LoadClass query can be useful to experiment with loading classes from different initial loaders.

If the correct initial loader was used, then a code source is likely missing in the search path. See "NoClassDefFoundError" for more detail.

NoClassDefFoundError

This exception can occur when the VM attempts to resolve a static dependency from one class to another. It is a type of LinkageError that indicates that the required class is not visible from the initiating loader. Since static dependency resolution is often deferred until first use, this error can occur at unexpected times.

Example Error Message

Missing class: acme.Dynamite

        Dependent class: acme.RoadRunner
Loader: acme.root:0.0.0
Code-Source: /myapps/acme/acme.jar
Configuration: <ejb> in /myapps/acme/application.xml

The missing class is available from the following locations:

1.      Code-Source: /shared/bang/0.0.0/bang.jar (from <code-source> 
in j2ee/home/server.xml)

This code-source is available in loader bang:0.0.0. This 
shared-library can be imported by the "acme" application.

How to troubleshoot and resolve

Examine the error message. The first line names the missing class. The next four lines describe the class that has the dependency: its name, the loader that defined it (also the "initiating" loader, selected by the VM), the code source from which it came, and the configuration option that caused the code source to be added to that loader. Subsequent lines describe the result of the diagnostic search, and will likely provide enough detail to resolve the issue.

Some common conditions reported by the diagnostic search follow, each with specific suggestions for resolution:

  • The missing class is not present in any code source visible to the system.

    This often simply means that another code source must be added (which in turn may require others). Use the dependent class information to choose the right level at which to add the configuration, and then select a convenient option (see Table 3-1, "Configuration Options That Affect Class Visibility"). Consider creating a new shared library if other applications are likely to need the same classes. Once created, the new shared library must also be imported.

    This result can also mean that an existing code source declaration is invalid. When a path is encountered that does not point to a valid file or directory, this fact is logged, but at a level that is normally masked. To see all messages, start the system with the following setting:

    -Dclass.load.log.level=finest

    Look for messages about nonexistent code sources, find the relevant one, and correct the configuration. There are often may of these messages, so it may be helpful to direct the output to a file (for example, "loader.log") that can be more easily searched:

    -Dclass.load.log.file=loader.log

  • The missing class is present in a shared library, but that shared library was not imported.

    Import the shared library, either with Application Server Control or by adding an <import-shared-library> element to the orion-application.xml deployment descriptor for the application.

  • The missing class is present, but the loader configured to use it is a child of the initiating loader.

    This most often occurs when a class deployed in an application root loader (for example, an EJB module) has a dependency on a class deployed in a Web module. Resolving requires either refactoring to eliminate the dependency or moving the classes into the same loader. Often, the simplest solution is to move such classes from the Web module up to the application root, but the reverse may also be possible. See Table 3-1 for options to add code sources to the root.

    Copying rather than moving such classes can lead to a ClassCastException when the search-local-classes-first option in the Web module is enabled.

  • The missing class is present, but the loader configured to use it is in an unrelated application.

    An ideal solution in this case is to move the relevant code sources out of the existing application into a new shared library and reconfigure both applications to import it. When this is not practical, the code source can be copied into the current application. While it is possible to use configuration to point directly at the code source in the other application, this will cause failures if that application is ever undeployed.

    The ClassPath query can be useful for examining code-source search order from a specific loader:

    -Doc4j.start.query="ClassPath(acme.root)+Exit"

    The SharedLibraries query can also be used to list all shared libraries and the loaders that import them.

ClassFormatError

This error can occur when a class is first loaded (during definition). It is a type of LinkageError, and often indicates that the class was compiled for a different version of the JVM.

How to troubleshoot and resolve

The error message will specify the version with which the class was compiled, and the version supported by the current runtime.

To correct the failure, either switch to the correct version of JVM, or recompile the class for the current one.

LinkageError

This error can occur when a class is first loaded (during definition). The more common LinkageError subtypes are processed as special cases by the OC4J class-loading framework (see "NoClassDefFoundError" and "ClassFormatError". The remaining cases generally indicate one of the following problems:

  • The version of a class used at compile time does not match the version found at runtime.

  • A native library is required but cannot be found.

The error message will specify the actual failure, and will also provide the name, defining loader, code source, and configuration for two different classes: the one that failed during definition, and the class that has the dependency that caused the definition to occur.

If the message indicates a version mismatch of some sort, such as NoSuchMethodError, source level changes and recompilation will be required to resolve the failure. Frequently, the mismatch occurs between a superclass or interface and a subclass, and should be relatively easy to discern.

An UnsatisfiedLinkError means that a native library could not be found. Generally, OC4J only supports configuring native libraries within RAR modules (see Table 3-1, "Configuration Options That Affect Class Visibility"). If the library is specified within a RAR, it may be an invalid path. See "NoClassDefFoundError" for a discussion of using the class.load.log.level property to detect this case.

ClassCastException

This exception usually occurs for obvious reasons, such as:

Object source = new Integer(0);
String target = (String) source; // Exception

However, this exception can also be related to class loading. Unfortunately the error message created by the VM is normally empty, and even when this exception is loading related, it cannot be intercepted and annotated.

When more than one loader defines a class with the same name, a cast between the two types will fail with a ClassCastException:

import com.acme.Foo;
...
// Get the loader that resolves our static dependency
// on class Foo

ClassLoader expected = Foo.class.getClassLoader();

// Dynamically load Foo from another loader and
// create an instance

Class fooClass = aLoader.loadClass("com.acme.Foo");
Object source = fooClass.newInstance();
ClassLoader actual = fooClass.getClassLoader();

// Compare and cast

System.out.println(actual == expected); // "false"
Foo target = (Foo) source; // Exception

In this case, the loader instances are different, and so the JVM considers the two classes to be unrelated.

A relatively common example of this problem happens within a single application when an EJB interface is packaged both in the EJB module and in a Web module that uses the EJB module. If the search-local-classes-first option is enabled for the Web module, the EJB classes will be loaded twice.

First, determine the target type of the cast by looking at the code described at the top of the stack trace. If the cast is to a primitive type (such as int or long) or to a class defined by the JRE (for example, String, HashMap, or any other java.* class), then it is almost certainly not related to class loading and is a (usually simple) developer error.

Next, use tracing to see definition(s) of the target class. For example, if the target of the cast is com.acme.Foo, use:

-Dclass.load.log=class-defined:com.acme.Foo

The output will describe the loader and the code source from which the class is defined. If there is only one, then the problem is unlikely to be related to class loading (though it is still possible if custom class loaders are in use because they do not participate in tracing).

If there is more than one definition of the target class, then it is very likely that they are coming into contact and causing the exception. If the trace messages list the same code source for both definitions, then it is being shared across loaders and should be easy to re-arrange.

However, it is far more common that the code sources will be different, perhaps because classes were repackaged for convenience (nearly always a bad idea), or because they are different versions. If one of the loaders is from a Web module, disabling search-local-classes-first may be sufficient.

If the code can be instrumented, duplication can be confirmed by adding code just before the cast (where obj is the object being cast):

ClassLoader expected = Foo.class.getClassLoader();
System.out.println("Expected: " + expected);
ClassLoader actual = obj.getClass().getClassLoader();
System.out.println("  Actual: " + actual);

The output should agree with the loaders named in the tracing messages. If obj is a subclass of the expected type, then walking the hierarchy with Class.getSupertype() may be required.

If duplication is confirmed as the cause, every duplicate class must be eliminated. This can be accomplished by arranging for the class to be shared; either move the class to a common parent of the two loaders or to a shared library. To help determine which loader should continue to load the class, it might be helpful to see the call stack at the point of each class definition:

-Dclass.load.log=class-defined:com.acme.Foo+stack

It might also be useful to see the relationships between loaders using the LoaderTree query:

-Doc4j.start.query=LoaderTree

Queries can also be executed on a running instance using the System MBean Browser in Application Server Control. The -verbose option can be used with this query to see lots of detail:

-Doc4j.start.query="LoaderTree(-verbose)+Exit"

The DuplicateClasses query can also be used to search for potential duplicates (same class name in different code sources).

Tracing Class-Loading Events to Help Troubleshoot Issues

OC4J provides the class.load.log system property that can be set to trace class loading, class-loader life cycle, and code-source life-cycle events. The tracing output generated can be extremely useful in troubleshooting issues related to class loading.


Note:

This feature is subject to change in future releases of OC4J.

The class.load.log property is set at OC4J startup. The syntax follows:

class.load.log=<event>[[:<string-filter>[,<string-filter>]] |
 [~<pattern-filter>]]
  • <event> is the event to trace. See Table 3-26 for valid values.

    Multiple event values can be strung together with a + character.

    -Dclass.load.log=class+loader 
    
  • <string-filter> is a filter applied to manage trace output. Note that a colon (:) separates the initial filter from the event. See "Using Filters to Manage Trace Output" for details on the types of filters that can be applied to manage trace output.

    Multiple filters can be separated by a comma:

    -Dclass.load.log=class:com.acme.Foo,com.acme.Bar
    
  • <pattern-filter> is a single filter that is interpreted as a regular expression. Note that a ~ character precedes the filter.


Notes:

  • System properties must be prefaced on the command line with a -D. For example:

    java -Dclass.load.log=loader -jar oc4j.jar
    
  • In a standalone OC4J configuration, system properties are set directly on the oc4j.jar command line, as shown in the preceding example.

  • In an Oracle Application Server configuration, system properties are set in the <data> element where the id attribute is "java-options" in the opmn.xml file for the OC4J instance. For example:

    <data id="java-options" value="-Dejb3=true  -Dclass.load.log=class+loader"/>
    

Trace output is written to the console by default, but can be written to a file specified using the class.load.log.file system property. For example:

java -Dclass.load.log.file=C:\logs\logfile.txt -jar oc4j.jar

Table 3-26 class.load.log System Property Values

Value Description

all

Activate all tracing modes. Note that setting this value may slightly impact OC4J performance, due to the volume of output.

none

Disable all tracing modes.

class

Trace all class-loading search events.

class-defined

Trace all events in which the specified class is initially loaded by a class loader. The object is then cached for subsequent use by class loaders.

class-found

Trace all search events where the specified class was found.

class-not-found

Trace all search events where the specified class was not found.

code-source

Trace all code source life cycle events.

code-source-create

Trace events where a code source object is first initialized. Only one instance of a code source is created in memory; this object is then shared by all class loaders that need it.

code-source-dependency

Trace events for all code sources where extension dependencies declared in the MANIFEST.MF file packaged within the archive were found or not found.

code-source-dependency-satisfied

Trace events for all code sources where all extension dependencies declared in the MANIFEST.MF file packaged within the archive were found.

code-source-dependency-not-satisfied

Trace events for all code sources where all extension dependencies declared in the MANIFEST.MF file packaged within the archive were not found.

code-source-manifest

Trace events for all code sources where a MANIFEST.MF file is packaged within the archive and any class paths, extension declarations, etc. are being processed.

code-source-state

Trace events for two the following code source states:

  • Open: Code source is actively being searched for or used by a class loader.

  • Closed: Code source is not currently being used by a class loader and is basically in a passivated state.

code-source-destroy

Trace events where a code source object is being destroyed.

loader

Trace all class-loader life-cycle events.

loader-create

Trace class-loader object-instantiation events.

loader-commit

Trace events where a class-loader object has been created and populated with classes from code sources.

loader-finalize

Trace events where the finalize() method has been called on a class-loader object and the object is no longer accessible.

loader-close

Trace events where a class-loader object is in the process of being garbage collected by the JVM.

loader-destroy

Trace events where a class-loader object is being destroyed.

resource

Trace all resource search events.

resource-found

Trace all resource search events where the resource was found.

resource-not-found

Trace all resource search events where the resource was not found.

stack

Add a stack trace to all events.

help or ?

Print the help text to the console.


Using Filters to Manage Trace Output

The class.load.log system property supports the use of filters to make event tracing output more manageable. The syntax is as follows. Note that a colon (:) separates the initial filter from the event to trace:

<event>[[:<string-filter>[,<string-filter>]] | [~<pattern-filter>]]

Table 3-27 describes the supported event filter types.

Table 3-27 Supported Trace Output Filters

Event Supported Filters

class

  • Exact match

    Specify the fully qualified name of the class to trace events for. The following example will only trace loading of the com.acme.Dynamite class:

    -Dclass.load.log=class:com.acme.Dynamite
    
  • Prefix or suffix match

    Use a leading or trailing asterisk (*) to treat the string as a prefix or suffix. For example:

    -Dclass.load.log=class:com.acme.*
    -Dclass.load.log=code-source:*foo.jar
    
  • Regular expression match

    Use a tilde (~) to treat the string as a regular expression. The .* syntax indicates that any number of characters can match the expression.

    The following example will trace class-loading events for class names containing "util":

    -Dclass.load.log=class~.*util.*
    
  • Class loader match

    Begin the filter string with loader. to treat the remainder of the string as a class-loader name.

    The following example will trace loading only of classes performed by the api class loader, the default parent of all application-specific class loaders:

    -Dclass.load.log=class:loader.api
    

code-source

  • Full path

    Specify the full path for the code source to trace events for. For example:

    -Dclass.load.log=code-source:/C:/oc4j/xdk/lib
    
  • Partial path

    Use a leading or trailing asterisk (*) to treat the string as a prefix or suffix. This example will trace loading only of classes in the com.acme package:

    -Dclass.load.log=code-source:*/acme.jar
    -Dclass.load.log=code-source:/C:/oc4j/*
    
  • Regular expression match

    Use a tilde (~) to treat the string as a regular expression. The .* syntax indicates that any number of characters can match the expression.

    The following example will trace code-source-create events for the "foo" application:

    -Dclass.load.log=code-source-create~.*/foo/.*
    

loader

  • Exact match

    Specify the complete name (name.name:version) of the class loader to trace events for. For example:

    -Dclass.load.log=loader:oracle.jdbc:10.1.0_2
    
  • Suffix match

    Use a trailing asterisk (*) to treat the string as a suffix. For example:

    -Dclass.load.log=loader:oracle.jdbc:*
    
  • Regular expression match

    Use a tilde (~) to treat the string as a regular expression. The .* syntax indicates that any number of characters can match the expression.

    The following example will trace create events for application root class loaders:

    -Dclass.load.log=loader-create~.*root.*
    

resource

  • Full path

    Specify the full path for the resource. For example:

    -Dclass.load.log=resource:META-INF/services/
      javax.xml.parsers.DocumentBuilderFactory.
    
  • Partial path

    Use a leading or trailing asterisk (*) to treat the string as a prefix or suffix. For example:

    -Dclass.load.log=resource:*Messages_en.properties
    -Dclass.load.log=resource: oracle/oc4j/admin/jmx/model/*
    
  • Regular expression match

    Use a tilde (~) to treat the string as a regular expression. The .* syntax indicates that any number of characters can match the expression.

    The following example will trace all resource searches for property files with "security" in the path:

    -Dclass.load.log=resource~.*security.*properties
    

Setting Class-Loader Log Levels

By default, the class-loader logger messages are filtered at the CONFIG Java log level. If necessary, you can use the class.load.log.level system property to change the log level. Table 3-28 lists the values that can be set on this property.

For example, to set the log level to SEVERE:

-Dclass.load.log.level=severe

Note that tracing-related messages are written at the INFO log level. As a result, avoid setting the log level above INFO, such as to WARNING, to prevent these messages from being filtered from the logger output.

Table 3-28 class.load.log.level System Property Values

Value Description

all

Output all log messages.

severe

Output messages at the SEVERE level only.

warning

Output messages at the WARNING level or above.

info

Output messages at the INFO level or above. If the log level is set below info, for example, to finer, trace output will be filtered from the logger output.

config

Output messages at the CONFIG level or above. This is the default log level.

fine

Output messages at the FINE level or above.

finer

Output messages at the FINER level or above.

finest

Output messages at the FINEST level or above.

off

Suppress all logging messages.