Skip Headers

Oracle® Containers for J2EE Developer's Guide 10g Release 3 (10.1.3) Part No. B14433-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# 3 Utilizing the OC4J Class Loading Framework

This chapter provides guidelines on understanding and using the new class loading framework provided in OC4J. Discussions on common classloader problems and recommendations for avoiding them are also provided.

The following topics are included:

- Class Loading in OC4J

- Configuring an Application to Import a Non-Default Version of a Shared Library

- Removing and/or Replacing an Oracle Shared Library Imported by Default

- Using a Packaged JAR In Place of an Oracle Shared Library

- Installing and Publishing a Shared Library in OC4J

- Configuring an Application to Import a Shared Library

- Sharing Libraries Using the /applib Directory

- Class Loading Best Practices

- Troubleshooting Class Loading-Related Problems in OC4J

## Class Loading in OC4J

This section contains the following topics:

- What Is Class Loading?

- Class Versioning with Shared Libraries in OC4J

### What Is 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 classloaders, subclasses of the `java.lang.ClassLoader` class that find and load class files at runtime. Classloaders provide an abstraction that allows the JVM to load classes without any knowledge of where the class bytes come from, to enable both local and remote storage as well as dynamic class generation.

Each classloader works with one or more code sources - root locations from which the classloader 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 classloaders are linked together in a parent-child hierarchy, with each classloader having an associated parent classloader. This hierarchy represents a tree structure, ranging in complexity from simple chains to complex multi-branched trees.

In this hierarchy, a child classloader imports a set of classloaders 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 classloader created at the application level imports a set of classloaders from the `system.root` classloader.

See Figure 3-1 below for a graphical representation of the classloader tree structure used in OC4J.

### Class Versioning with Shared Libraries in OC4J

The classloader 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 application hierarchy in OC4J.

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

Figure 3-1 below illustrates the classloader tree structure in OC4J.

Figure 3-1 The OC4J Classloader Tree

Description of the illustration jidev001.gif

- 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 classloader 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` classloaders each contain Web module - classes packaged within a WAR file.

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

The OC4J shared classloaders - `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:

- 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`; and

- One or more code sources - JAR or ZIP files - containing the classes that comprise the library.

Classloaders are created at runtime based on the shared library definitions within the OC4J instance. Classloaders 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.

Note how 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 classloaders 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.

### What Shared Libraries Do Applications Import by Default?

The default set of shared libraries imported by all application classloaders within the OC4J instance is specified within the `imported-shared-libraries` element in `ORACLE_HOME``/j2ee/home/system-application.xml`. This is the configuration file for the `system` application, which is the parent of all applications within the OC4J instance.

The following are the key Oracle shared libraries that an application deployed to an OC4J instance will inherit by default:

- `oracle.jdbc:10.1.0_2`

- `oracle.xml:10.1.0_2`

- `oracle.cache:10.1.3`

- `oracle.http.client:10.1.3`

- `oracle.sqlj:10.1.3`

- `soap:10.1.3`

- `oracle.jwsdl:10.1.3`

## Configuring an Application to Import a Non-Default 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" for an end-to-end example

- "Example: Configuring an Application to Use a DataDirect JDBC Driver" for another complete example

- "Installing and Publishing a Shared Library in OC4J" for additional options for creating shared libraries

- "Configuring an Application to Import a Shared Library" for additional options for configuring applications to import a particular shared library

### 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, an earlier version of the Oracle JDBC driver than the version packaged with OC4J.

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 will illustrate this task using Application Server Control Console.

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 classloader. 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 using Application Server Control Console.

1. Select Applications>Deploy to launch the Application Server Control Console 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. Note that both versions of the oracle.jdbc shared library are listed in the Import Shared Libraries frame. 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, note the following entry in the application's `orion-application.xml` file:

       <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 this task using Application Server Control Console.

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 the shared library version, for example: 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 at the time the application is deployed using Application Server Control Console.

1. Select Applications>Deploy to launch the Application Server Control Console 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, note the following entry in the application's `orion-application.xml` file:

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

## Removing and/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.

Shared libraries inherited by default can be removed using one or more `<remove-inherited>` subelements within an `<imported-shared-libraries>` in the application's `orion-application.xml` file. 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>

See the following sections for complete examples:

- Example: Replacing the Oracle XML Parser with the Xerces Parser

- Example: Removing an Oracle Shared Library at Deployment Time

### 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 using Application Server Control Console. 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 will illustrate this task using Application Server Control Console.

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 using Application Server Control Console.

1. Select Applications>Deploy to launch the Application Server Control Console 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 using Application Server Control Console.

1. Select Applications>Deploy to launch the Application Server Control Console 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. Un-check 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 In Place 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, then force the application to use it in place of the Oracle XML parser or JDBC driver installed with OC4J—without having to declare the JAR as a shared library within OC4J.

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 into OC4J, the application will not import the default library installed with OC4J, causing the application's classloader 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 un-comment the `<web-app-class-loader>` element in this file. Next, set the `search-local-classes-first` attribute to `true` in this element will cause the classloader to find and load any libraries packaged in the WAR, and use these rather than corresponding libraries packaged with OC4J.

See "Example: Specifying search-local-classes-first at Deployment Time" below for details on how you can do this at deployment time using Application Server Control Console.

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>

Note that 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.

### Example: 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. this at the time the application is deployed using Application Server Control Console.

1. Select Applications>Deploy to launch the Application Server Control Console 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 re-use.

## 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 comprising 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 Should You Use a Shared Library?

- Options for Installing and Publishing a Shared Library

- How a Shared Library is Installed and Published in an OC4J Instance

### When Should You Use a Shared Library?

Typically, applications deployed into 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 then 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/home/shared-lib` directory and make the required entry in `server.xml`.

- Oracle Enterprise Manager 10g Application Server Control Console

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

- The `publishSharedLibrary` Ant task

  Allows you to install a shared library on a single OPMN-managed OC4J instance or on a standalone OC4J server.

- The `-publishSharedLibrary` command in `admin_client.jar`

  Also allows 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 following the process outlined in the next section, "How a Shared Library is Installed and Published in an OC4J Instance".

### How a Shared Library is Installed and Published in an OC4J Instance

Shared libraries are installed in the `ORACLE_HOME``/j2ee/home/shared-lib` directory in OC4J. The process includes creating the correct directory structure within this directory, then copying the JAR files that comprise the library into it.

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

First, the following directory structure for the library is created within this directory:

    ORACLE_HOME/j2ee/home/shared-lib
      /library_name
        /version
          filename.jar
          filenamejar
          ...

- `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.

Once these directories have been created, copy each JAR or ZIP file containing the classes that comprise the shared library into the `version` subdirectory. For example, assume the sample library consists of `acme-apis.jar` and `acmeImpl.jar`.

Given the examples above, the resulting directory structure within the OC4J server would be:

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

Multiple versions of the shared library are installed by creating a new subdirectory for each version's archive files within this directory structure, as illustrated below:

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

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

- 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.

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

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

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

Note that you can optionally 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 optionally take one or more `<import-shared-library>` elements, each specifying a shared library to be imported by the shared library being configured. Note that an imported shared library must also be installed and published on the OC4J host.

The following example 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 sample entries above would resolve to:

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

## 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:

- Declare a dependency in an application's OC4J-specific `orion-application.xml` deployment descriptor.

  See "Declaring Dependencies in an Application's OC4J Deployment Descriptor" for details.

- Declare a dependency using an application's `MANIFEST.MF` file.

  This is the standard J2EE standard mechanism for declaring dependencies on "installed" libraries. See "Declaring Dependencies in an Application's Manifest File" for details.

- Force all applications deployed to the OC4J instance to use the shared library by declaring a dependency in `application.xml`, the configuration file for the `default` application. Because `default` is the parent of all other applications deployed to the instance, the shared library will be imported by these applications.

  See "Configuring All Deployed Applications to Import a Specific Shared Library" for details.

- Configure the application to import the shared library at deployment time via the deployment tasks provided in Application Server Control Console. The deployment tasks mechanism updates the application's `orion-application.xml` file as outlined in this section.

  See the Oracle Containers for J2EE Deployment Guide for details on using this feature.

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 allow 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 file within a shared library. This is the standard J2EE mechanism for declaring dependencies on installed libraries.

To use this mechanism, the dependent JAR 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. Note that the value of the `name``-Extension-Name` attribute exactly matches the `Extension-Name` specified in the JAR file's manifest:

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

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

    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 other applications deployed to OC4J, any shared libraries it 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/home/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 and/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 files to be shared are installed in the `ORACLE_HOME/j2ee/home/applib` directory, is still supported in the current release of OC4J. All JAR files within this directory will be included in the `global.libraries` shared library, and will be available to all applications within the OC4J instance.

Be advised that support for this legacy functionality will be removed in a future release of OC4J. You are strongly encouraged to use the new shared library mechanism documented in this chapter whenever possible.

## Class Loading Best Practices

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 Classloader

If you use reflection by calling `Class.forName()`, always explicitly pass the classloader returned by `Thread.currentThread().getContextClassLoader`. If you are loading a properties file, use `Thread.currentThread().getContextClassLoader().getResourceAsStream()`.

## Troubleshooting Class Loading-Related Problems in OC4J

OC4J provides features to help you troubleshoot class loading-related issues.

- Overview of Troubleshooting

- Classloader-Related Errors and Exceptions

- Using Queries to Troubleshoot Class Loading Issues

- Tracing Class Loading Events to Help Troubleshoot Issues

- Setting Classloader Log Levels

### Overview of Troubleshooting

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": the search path across a set of loaders and the code-sources (e.g. JARs and/or directories) they contain.

In JavaSE, the class-path is usually thought of as the list of code-sources specified on the command-line or in the manifest Class-Path of the main jar. 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 JARs in the jre/lib/ext directory) and the JRE bootstrap loader (containing rt.jar etc.)

The idea that there is a class-path is often quite misleading. For each class lookup, the search begins at a specific loader, and (normally) can only visit loaders "above" it. 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 JavaEE, 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 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.

This can easily be seen by making the following call from within different modules, as OC4J ensures that the correct class-path is returned for the calling module:

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

There are many configuration options that affect class visibility for applications. Table (UNKNOWN STEP NUMBER) lists the most common options within OC4J. Given the possible combinations of loaders and code-sources in a JavaEE 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 Affecting Class Visibility

Classloader | 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> jars/directories in `orion-application.xml`
| <ejb> JARs in `orion-application.xml`
| RAR file: all JARs at the root.
| RAR file: <native-library> directory paths.
| Manifest Class-Path of above JARs
`app-name.web.web-mod-name` | WAR file: Manifest Class-Path
| WAR file: WEB-INF/classes
| WAR file: WEB-INF/lib/ all JARs
| <classpath> jars/directories in `orion-web.xml`
| Manifest Class-Path of above jars.
| search-local-classes-first attribute in `orion-web.xml`
| Shared libraries are inherited from the app root.

### Classloader-Related Errors and 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:

- ClassNotFoundException

- NoClassDefFoundError

- ClassFormatError

- LinkageError

- ClassCastException

The subclasses enhance the output of the `getMessage()`, `printStackTrace()` or `toString()` methods with information to help 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.

Note that 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 always chooses 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);

Note that 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 are listed below, 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 Affecting Class Visibility"). Consider creating a new shared-library if other applications are likely to need the same classes. Note that 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 "non-existent" 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 through Application Server Control Console or by adding an `<import-shared-library>` element to 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) 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, "Configuration Options Affecting Class Visibility" for options to add code-sources to the root.

  Note that 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 may 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 to examine code-source search order from a specific loader:

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

  The `SharedLibraries` query may 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 re-compile 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 system (see NoClassDefFoundError and ClassFormatError) -- the remaining cases generally indicate one of the following:

- A mismatch between the versions of a class used at compile time and that found at runtime

- A native library is required but cannot be found.

How to troubleshoot and resolve

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 re-compilation 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 Table 3-1, "Configuration Options Affecting 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 class loading related. 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. If the search-local-classes-first option is enabled for the web-module, the EJB classes will be loaded twice.

How to troubleshoot and resolve

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 class loading related 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.trace=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 class loading related (though it is still possible if custom class loaders are in use, as they won't 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 re-packaged 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. Note that 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, it 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 may be helpful to see the call stack at the point of each class definition:

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

It may 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 ASControl system MBean browser. 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 names in different code-sources).

### Using Queries to Troubleshoot Class Loading Issues

OC4J provides a number of built-in queries that can be run to troubleshoot classloader-related problems. Queries can be executed at OC4J startup by setting the `oc4j.start.query` system property, or at runtime through the `ClassLoading` MBean.

- Summary of Available Queries

- Executing Queries at OC4J Startup

- Executing Queries at Runtime via the `ClassLoading` MBean

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

#### Summary of Available Queries

The following built-in queries are provided with OC4J to assist in troubleshooting class loading-related problems.

Note that the examples used illustrate usage of the `oc4j.start.query` system property, which is set on the `oc4j.jar` command line at OC4J startup.

The available queries are as follows:

- Callers

- ClassLoadMetrics

- ``ClassPath

- Dependencies

- Depends

- DuplicateClasses

- DuplicateCodeSources

- Exit

- FindResource

- ListQueries

- LoadClass

- LoaderTree

- ``SharedLibraries

- SystemProperties

- UnusedCodeSources

- Uptime

Callers

Reports all classes that call the specified method(s). The query optionally takes the name of a classloader to limit the query to.

For example, to find all classes that call `System.currentTimeMillis()`, execute the following:

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

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

    -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)

Note that you can include "`<init>`" in the `<signature>` argument to specify a constructor:

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

Arguments: `[-<loaderName> <signature>...`

Table 3-2 Callers Query Arguments

Argument | Description
--- | ---
`-loaderName` | Optional. If specified, all classes visible from the classloader will be checked for the specified methods. If not specified, all classes visible to all classloaders down the tree from the `api` classloader - the default parent of all application-specific classloaders - are checked.
`signature` | Required. A method to check for. Multiple methods may be specified, each as a separate argument. The syntax is: `class-type``.``method-name``[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, the `return-type` may be omitted.

ClassLoadMetrics

Reports metrics for the specified classloader(s), or for all classloaders if none are specified. For example:

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

Arguments: `[-verbose] [<loaderName>]...`

Table 3-3 ClassLoadMetrics Query Arguments

Argument | Description
--- | ---
`-verbose` | Optional. Supply to generate detailed metrics.
`loaderName` | Optional. The name(s) of the class loader(s) to report metrics for.

``ClassPath

Reports the code-sources in use.

Arguments:`[-list] [loaderName]`

Table 3-4 ClassPath Query Arguments

Argument | Description
--- | ---
`-list` | Optional. Include to generate a line-separated, numbered list of code-sources.
`loaderName` | Optional. If specified, the classloader is used as the starting point from which the classpath is computed. Otherwise, the classpath defaults to the internal `oc4j` classloader, which loads all OC4J system classes.

Dependencies

Reports all dependencies of the specified class.

Arguments: `<className> [loaderName] [-r]`

Table 3-5 Dependencies Query Arguments

Argument | Description
--- | ---
`className` | The fully qualified name of the class to report dependencies for.
`loaderName` | Optional. If specified, the classloader is used as the starting point from which depedencies are determined. Otherwise, the the internal `oc4j` classloader, which loads system classes, is used.
`-r` | Optional. Set to search classes recursively. Note that use of this option can cause long execution times.

Depends

Reports on all classes that are dependent on the specified class.

Arguments: `[-loaderName] <className>`

Table 3-6 Depends Query Arguments

Argument | Description
--- | ---
`className` | The fully qualified name of the class to check for dependencies. To specify an entire package, use an asterisk (`*`) as the leaf name.
`loaderName` | Optional. If specified, all classes visible to the classloader will be checked. Otherwise, all classes visible to all classloaders from the `api` classloader downwards are checked.

DuplicateClasses

Reports the existence of classes/resources with the same name in different code sources.

Arguments: None

DuplicateCodeSources

Reports code-sources that have the same name or have more than one subscriber.

Arguments: `[-digest]`

Table 3-7 DuplicateCodeSources Query Arguments

Argument | Description
--- | ---
`-digest` | Optional. If specified, bit-wise comparisons of code-sources will be performed.

Exit

Exits the process and shuts down OC4J if running. This is useful if you only want to execute the query without leaving the OC4J server running. For example:

    -Doc4j.start.query=LoaderTree+Exit

Arguments: `[-force]`

Table 3-8 Exit Query Arguments

Argument | Description
--- | ---
`-force` | Optional. Forces a `System.exit()` call instead of a normal shutdown.

FindResource

Reports the code-sources containing the specified resource, identified either by classname or resource path.

A leading or trailing asterisk `*` can be used for a simple wildcard search, or a leading `~` may be used to indicate that the argument should be treated as a regular expression.The `resourcePath` argument must be passed to search for classes with no package. For example, to find class foo, the query would be:

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

To search for resources with no package (`/`), where the resource name contains a period (`.`), a leading asterisk must be used. For example, use the following query to find the `myconfig.xml` file at the root of a code-source:

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

Arguments: `[-list] <resourcePath>|<className>`

Table 3-9 FindResource Query Arguments

Argument | Description
--- | ---
`-list` | Optional. Can be used with wildcard or regular expressions to list all matching resources.
`resourcePath` | The fully qualified path to the resource. Either `resourcePath` or `className` must be supplied.
`className` | The fully qualified classname of the resource to search for. Either `resourcePath` or `className` must be supplied.

ListQueries

Lists all of the available queries in OC4J, by `oracle.oc4j.query.Query` subclass name.

Arguments: None

LoadClass

Attempts to load the specified class using the specific classloader, or using the internal `oc4j` classloader if none specified, and reports the result. The query in effect performs a class loading "test run".

Arguments: `<className> [loaderName] [-forName] [-depends] [-r] [-sort]`

Table 3-10 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 classloader are reported. If not specified, the `oc4j` classloader is used by default.
`-forName` | Optional. The classloader method to record attempts for. If not specified, `loader.loadClass()` is used by default.
`-depends` | Optional. Specify to force the classloader 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.

LoaderTree

Reports the contents of the classloader tree for the specified root classloader, or for the JRE's bootstrap classloader if none specified. By default, only the names of the classloaders within the tree are reported.

This query is useful if you want to focus on a specific part of the classloader tree, such as from the root of a specific application downwards. For example:

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

To retrieve the entire classloader tree, do not include a root classloader name:

    -Doc4j.start.query=LoaderTree

Arguments: `[rootLoaderName] [-verbose]`

Table 3-11 LoaderTree Query Arguments

Argument | Description
--- | ---
`rootLoaderName` | Optional. The root classloader name. If not specified, reports the contents of the JRE's bootstrap classloader tree.
`-verbose` | Optional. Specify to output detailed information. If not specified, only the names of the classloaders within the tree are reported.

``SharedLibraries

Lists all installed shared libraries and the class loaders that import each.

Arguments: `[loaderName]`

Table 3-12 SharedLibraries Query Arguments

Argument | Description
--- | ---
`loaderName` | Optional. If specified, lists shared libraries imported by the specified classloader. Otherwise, the shared libraries imported by all classloader instances are listed.

SystemProperties

Reports the contents of the System properties.

Arguments: None

UnusedCodeSources

Reports code-sources that have never retuned any data.

Arguments: None

Uptime

Reports the length of time the current OC4J server instance has been running.

Arguments: None

#### Executing Queries at OC4J Startup

Queries can be executed at OC4J startup by setting the `oc4j.start.query` system property on the `oc4j.jar` command line.

Query results are written to the file specified as the value of the `class.load.log.file` property, or to the console (`System.out`) if no file is specified. See "Setting Classloader Log Levels" for details on the `class.load.log.file` property.

Note that system properties must be prefaced on the command line with a `-D`. The syntax is as follows:

    java -Doc4j.start.query=<queryName>(arg0,arg1,...) -jar oc4j.jar

Arguments can be passed in with the query by appending `(arg0,arg1,...)`to the query name. Note that arguments are enclosed in parentheses. Multiple arguments are separated by a comma.

Note: For some UNIX shells, the property value string—everything after the `=` symbol—will need to be quoted.

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

    java -Doc4j.start.query=DuplicateCodeSources(-digest) -jar oc4j.jar

Multiple queries may be specified by separating them with the `+` character:

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

#### Executing Queries at Runtime via 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 Console interface. See the Oracle Containers for J2EE Configuration and Administration Guide for details on accessing and using the MBeans packaged with OC4J.

1. Click the Administration link in the Application Server Control Console.

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.

### Tracing Class Loading Events to Help Troubleshoot Issues

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

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

The `class.load.trace` property is set at OC4J startup. The syntax is as follows:

    class.load.trace=<event>[[:<string-filter>[,<string-filter>]] |
     [~<pattern-filter>]]

- `<event>` is the event to trace. See Table 3-13 for valid values.

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

      -Dclass.load.trace=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.trace=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.trace=loader -jar oc4j.jar
- In a standalone OC4J configuration, system properties are set directly on the `oc4j.jar` command line, as shown in the example above. 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.trace=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-13 class.load.trace 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 classloader. The object is then cached for subsequent use by classloaders.
`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 lifecycle 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 classloaders 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 classloader. Closed: Code source is not currently being used by a classloader, and is basically in a passivated state.
`code-source-destroy` | Trace events where a code source object is being destroyed.
`loader` | Trace all classloader lifecycle events.
`loader-create` | Trace classloader object instantiation events.
`loader-commit` | Trace events where a classloader object has been created and populated with classes from code sources.
`loader-finalize` | Trace events where the `finalize()` method has been called on a classloader 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.trace` 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-14 describes the supported event filter types.

Table 3-14 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.trace=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.trace=class:com.acme.*
      -Dclass.load.trace=code-source:*foo.jar
- Regular expression match Use a tilde (`~`) to treat the string as a regular expression. Note that 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.trace=class~.*util.*
- Classloader match Begin the filter string with `loader.` to treat the remainder of the string as a classloader name. The following example will trace loading only of classes performed by the `api` classloader, the default parent of all application-specific classloaders:
      -Dclass.load.trace=class:loader.api
- `code-source` | Full path Specify the full path for the code source to trace events for. For example:
      -Dclass.load.trace=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.trace=code-source:*/acme.jar
      -Dclass.load.trace=code-source:/C:/oc4j/*
- Regular expression match Use a tilde (`~`) to treat the string as a regular expression. Note that 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.trace=code-source-create~.*/foo/.*
- `loader` | Exact match Specify the complete name (`name.name:version`) of the classloader to trace events for. For example:
      -Dclass.load.trace=loader:oracle.jdbc:10.1.0_2
- Suffix match Use a trailing asterisk (`*`) to treat the string as a suffix. For example:
      -Dclass.load.trace=loader:oracle.jdbc:*
- Regular expression match Use a tilde (`~`) to treat the string as a regular expression. Note that the `.*` syntax indicates that any number of characters can match the expression. The following example will trace `create` events for application root classloaders:
      -Dclass.load.trace=loader-create~.*root.*
- `resource` | Full path Specify the full path for the resource. For example:
      -Dclass.load.trace=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. This example will only trace loading of classes in the `com.acme` package:
      -Dclass.load.trace=resource:*Messages_en.properties
      -Dclass.load.trace=resource: oracle/oc4j/admin/jmx/model/*
- Regular expression match Use a tilde (`~`) to treat the string as a regular expression. Note that 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.trace=resource~.*security.*properties

### Setting Classloader Log Levels

By default, the classloader 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-15 below 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` - to `WARNING`, for example - to prevent these messages from being filtered from the Logger output.

Table 3-15 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. Note that 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.