How To: Swap Oracle JDBC Drivers

Initial Publication: 22-Nov-04

Updates:

  $Date: 2006-08-08 22:45:59 -0700 (Tue, 08 Aug 2006) $
  $Author: sbutton $

 

Date Who What
22-Nov-2004 sbutton Initial creation and publication for OC4J 10g (10.1.3) Developer Preview 3
26-Jul-2005 sbutton

Updated to use new capabilities within Application Server Control to create and configure shared libraries.

10-Jan-2006 sbutton Update for production
06-Aug-2006 sbutton

Included embedded DataSource to reduce required config steps
Included ojdbc14.jar within distribution
Added publish shared library target to create howto.jdbc shared-library -- example can constructed entirely via Ant if desired

Introduction

This how-to serves purely as a demonstration of the mechanics behind changing the version of the Oracle JDBC driver used by an application running on OC4J. It does not serve as a statement of certification for any specific OC4J/JDBC driver combination. All certification information should be obtained from Oracle Support or via the Oracle Metalink web site -- http://metalink.oracle.com.

This how-to demonstrates how the shared-library mechanism – introduced in OC4J 10g (10.1.3) – can be used to define which Oracle JDBC driver is loaded for a specific application.

Note: See the OC4J Configuration and Administration Guide for a detailed discussion on the shared libraries functionality available in OC4J.

This how-to contains an application which makes a database connection and prints out the version of the Oracle JDBC driver it has used. To demonstrate the shared-library capabilities, a different Oracle JDBC driver version is installed and published as a shared-library and the application is re-configured use the new shared-library.

Like many other application servers, OC4J is configured to load a pre-defined set of libraries. For instance, all of the J2EE libraries supported and implemented by a specific release are loaded when OC4J starts. Additionally, the Oracle JDBC drivers that ship with the distribution are also loaded and made available to applications by default. The standard approach is that the version of Oracle JDBC driver which is included is from the corresponding version of the database on which the OC4J version has been built and tested. Typically this is a handy situation for users of OC4J, eliminating the need to track down a set of JDBC drivers for use with an application.

However, there are situations where an application will requires a specific version of JDBC driver other that what has been provided with OC4J. Up until the 10.1.3 release, this has proven to be a non trivial problem for users of OC4J.

The main problem has been that the JDBC libraries have been hard coded into the classpath of the container using the referential JAR file Class-Path mechanism. Altering this has required the use of the JRE extension library mechanism, or altering the boot classpath of the JVM when it is launched to load the alternative JDBC driver version instead. While this works, it has been an unsupported operation, since the effect of this change is not limited to a specific application – the effect is felt across the entire container and may lead to unpredictable results at runtime. A similar situation has also arisen from time to time with the requirement to utilize a different XML parser implementation (such as Xerces) than the one baked into OC4J.

But a solution is now at hand with the introduction of the shared-library mechanism with OC4J 10g (10.1.3). Using the shared-library mechanism, classes can now exist within a parallel classloading space, enabling a clean separation to be made between the libraries used by OC4J itself and the libraries used by applications deployed to OC4J.

With this shared library implementation, it is possible to specifically override and replace any of the default class libraries which are loaded and made available by default. This can be done on an individual application-by-application basis or rolled up to a set of defaults inherited by each application.

A shared library consists of a set of code-sources from which Java classes can be loaded by a class loader. A shared library has a name and a version.

By default, an application deployed to OC4J inherits a number of pre-defined shared-libraries. The definitions for these shared libraries are shown below.

 <imported-shared-libraries>
                          

 <import-shared-library name="oracle.dms"/>
                          

  
                           <import-shared-library name="oracle.jdbc"/>
                          

<import-shared-library name="oracle.xml"/>
                          

<import-shared-library name="soap"/>
                          

<import-shared-library name="global.libraries"/>
                          

<import-shared-library name="global.tag.libraries" />
                          

</imported-shared-libraries>
                        

The definitions for the default set of shared-libraries are specified in an internal OC4J file which can't be changed. However, it's possible to install and publish additional shared libraries, then configure applications to load them and even replace any of the inherited libraries as needed.

This how-to demonstrates exactly how to perform this task.

What are the Prerequisites?

What Should You Know?

  • Be generally familiar with J2EE applications and JDBC
  • Have an an appreciation what class libraries are and how they are used in conjunction with J2EE containers.

What are the Software Requirements?

  • Have access to the scott schema in an Oracle database.
  • OracleAS or OC4J 10g (10.1.3) installed. Available from OTN.
  • Sun JDK 1.4_02 or above. Available from the Sun Web site.
  • Apache Ant 1.6.2. Available from the Apache Ant Web site.
  • Oracle JDBC Driver 9.2 to publish as a shared-library -- available for download from OTN -- Oracle JDBC 9.2 drivers.
    ** Note: ojdbc14.jar now included in ./lib directory

What are the Notations?

  • %ORACLE_HOME% : the directory in which OC4J has been installed.
  • %J2EE_HOME% : the directory where the oc4j.jar file exists within OC4J.
    This is typically 2 directories under %ORACLE_HOME%. For example, if you installed OC4J to c:\ then %J2EE_HOME% would be c:\j2ee\home
  • %JAVA_HOME% : the directory where the JDK is installed on your machine.

How to Build the Application?

This how-to needs to be built and deployed before it can be accessed.

Examining the How to Distribution

First off, let us examine the contents of the how-to distribution.

  • how-to-swapjdbclib/src - contains all Java source code for the example.
    • web/
      • index.jsp - the page used by the container to display the JDBC driver version.
      • css/
        • blaf.css - the style-sheet.
  • how-to-swapjdbclib/ etc/
    • web.xml - the standard J2EE Web module deployment descriptor
    • application.xml - the standard J2EE application module descriptor
    •  
    orion-application.xml - the OC4J specific deployment desciptor, defines the application data-sources.xml file and optionally the shared-library settings
    • data-sources.xml - contains a pre-defined, application level datasource and connection pool definition
  • how-to-swapjdbclib/doc/
    • how-to-swapjdbclib.html - this document.
    • images/ - contains the images for this document
  • how-to-swapjdbclib/lib
    • ojdbd14.jar - the Oracle 9.2.0.4 JDBC library for use in example
  • how-to-swapjdbclib/
    • build.xml - the Ant build file to build, package and deploy the application
    • oracle-ant.xml - sets correct environment up for Ant to to build and deploy the application
    • oracle-ant.properties - defines the properties of the OC4J instance which the application is deployed to

Setting Up the Application

Make sure the following properties are configured correctly in the oracle-ant.properties file located in the root directory of this how-to distribution.

NOTE:  Some of these properties will default to the values of corresponding environment variables as noted below.  If you have these variables setup in your environment you may not have to alter the values in the file.  If necessary, modify these variables to the proper values for you environment:

  • oracle.home - the root directory of oracle installation.  Defaults to the ORACLE_HOME environment variable.
  • java.home -  the root directory of JDK installation.  Defaults to JAVA_HOME environment variable.
  • oracleas.host - the hostname of the platform on which the target OC4J instance is running.  Defaults to localhost.
  • oracleas.http.port - the port on which the HTTP listener is listening.  Defaults to 8888.
  • oracleas.admin.port  - the port on which the OC4J administration processor is listening.  Defaults to 23791.
  • oracleas.admin.user - the name of the OC4J administrator.  Defaults to "oc4jadmin".
  • oracleas.admin.password - the password for the OC4J administrator.  Defaults to "welcome1".
  • oracleas.binding.module - the name of the HTTP web site to which the deployed application is bound.  Defaults to "http-web-site".
  • oracleas.deployer.uri - identifies the target for deployment operations -- enables OC4J standalone, OracleAS single instance or an OracleAS group to be deployed to using the same set of Ant tasks

In addition, please make sure that the ant command associated with the OracleAS ant distribution is in your execution path ( %ORACLE_HOME%/ant/bin).

The instructions from herein this document assume the use of the OC4J zip distribution. If OracleAS is being used, the appropriate commands required to start/stop the server should be used.

Start OC4J

Start your OC4J 10.1.3 instance as follows:

%ORACLE_HOME%/bin/oc4j start

The oc4j.cmd script expects the JAVA_HOME environment variable to point to a full JDK installation.

Deploying the Application

>ant

Executing the default all target of the supplied build.xml file performs the following steps:

  • Compiles all the source files
  • Packages the Web module into a WAR file and produces a J2EE application module (ear file) that contains the various files required for the deployment of the application.
  • Deploys the application module.  The .ear file generated in the previous step is now deployed to the server using the ant deploy ant task:      

<oracle:deploy
  deployerUri="${oracleas.deployer.uri}"
  userId="${oracleas.admin.user}"
  password="${oracleas.admin.password}"
  file="${dist.dir}/${app.name}.ear"
  deploymentName="${app.name}"
  bindAllWebApps="${oracleas.binding.module}"/>

Configuring an Application Specific Data Source

This application requires the use of a data source to establish a connection to a database from which it can determine the version of the JDBC driver that is loaded.

Because we are only wanting to alter the JDBC driver being used for a specific application and not all applications, we need to create an application specific data source.

The application in this how-to is hard coded to use a data source name of "jdbc/OracleDS", which must be a valid data source pointing to a running database instance.

The application therefore included a datasource definition file within its deployment archive which is instantiated when the application is started.

The embedded data-sources.xml file contains a definition of a connection-pool and a managed-data-source.

<?xml version = '1.0' encoding = 'UTF-8'?>
<data-sources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ... >
  <managed-data-source connection-pool-name="MyConnection" jndi-name="jdbc/MyDS" name="MyDS"/>

  <connection-pool name="MyConnection" inactivity-timeout="15">
    <connection-factory
      factory-class="oracle.jdbc.pool.OracleDataSource"
      user="scott"
      password="tiger"
      url="jdbc:oracle:thin:@localhost:5521:xe"/>
  </connection-pool>
</data-sources>

Note: before packaging and deploying the application, edit the etc/data-sources.xml file and set the relevant attributes within the connection-pool so to a valid database instance.

When the application is packaged the data-sources.xml file will be put in the META-INF directory of the EAR file and referenced from the orion-application.xml file.

How to Run this How-To

In this how-to you will perform a number of tasks to observe how shared-libraries can be used with OC4J.

The tasks you will now perform are:

  • Execute the deployed how-to-swapjdbclib application to view the version of the Oracle JDBC driver it loaded.
  • Install and publish a new shared-library with a different version of an Oracle JDBC driver.
  • Reconfigure the deployed application to override the default oracle.jdbc shared-library and load the new shared-library.
  • Re-execute the application and view the changed version of the Oracle JDBC driver that is loaded.

Determining the JDBC Driver Version

This how-to uses a simple application to view the version of the JDBC driver loaded by the application.

The application displays the version of the JDBC driver it has loaded by establishing a connection to a database and then utilizing the DatabaseMetaData object to obtain the JDBC driver name and version.

The code which obtains the JDBC driver version is shown below.

public static String getJdbcDriverVersion(String datasource)
                          

{
                          

 try
                          

 {
                          

 InitialContext context = new InitialContext();
                          

 DataSource ds = (DataSource)context.lookup(datasource);
                          

 Connection conn = ds.getConnection();
                          

 DatabaseMetaData metadata = conn.getMetaData();
                          

 conn.close();
                          

 return metadata.getDriverName() + " version " + metadata.getDriverVersion();
                          

 }
                          

 catch (Exception e)
                          

 {
                          

 return "Error, could not connect to \"" + datasource + "\"";
                          

 }
                          

}
                          

                        

Running the Application

Once the application has been deployed, you can observe what the version of the Oracle JDBC driver is is loaded by default by applications.

Open a browser window and enter the URL:

http://localhost:8888/how-to-swapjdbclib

This will display the version of the Oracle JDBC driver loaded.

On a default OC4J configuration this should read::

“The JDBC driver loaded is : Oracle JDBC driver version 10.1.0.4.0”

Note: the minor version of the file may change depending on which 10.1.3.x version of OC4J you are using.

The HTML page in the browser should look like the below:

 

Creating a Shared Library

You will now replace the version of the Oracle JDBC drivers the how-to-swapjdbclib loads.

To start with, you need a different JDBC driver version to use as a shared-library. The 9.2.0.4 version of the Oracle JDBC driver is supplied in the ./lib directory of this how-to for ease of use.

If you would like to use an entirely different version, the Oracle JDBC drivers from different releases are available from http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html.

For the rest of this document, it will be assumed that you have downloaded the Oracle JDBC 9.2.x drivers (ojdbc14.jar).

If you are using a different version of the Oracle JDBC drivers, then it shouldn't make any difference to the general running and progress of this how-to. There may be some slight filename changes across the different Oracle JDBC versions to be aware of.

A shared-library can be created and configured using Application Server Control Console (ASC) supplied with OC4J or with the Oracle Ant tasks.

Using Ant to Create a Shared Library

The Oracle Ant task set contain several shared-library related tasks to publish, modify and remove shared libraries.

To create the required oracle.jdbc:9.2 the <oracle:publishSharedLibrary> task is used:

<!-- ******************************************************
                          

** Creates the ${sharedLib.name} shared library
                          

** *************************************************** -->
                          

<target name="publish-shared-library" depends="init" description="Publishes howto.jdbc as a shared-library">
                          

   
                           <oracle:publishSharedLibrary
                          

      deployerUri="${oracleas.deployer.uri}"
                          

      userId="${oracleas.admin.user}"
                          

      password="${oracleas.admin.password}"
                          

     
                           libraryName="${sharedlib.name}"                             
libraryVersion="${sharedlib.version}">
<oracle:uploadCodeSource path="${lib.dir}/ojdbc14.jar"/> </oracle:publishSharedLibrary> </target>

This created the specified library name and version. It uploads the specified code-sources from the local file system to the target server and installs them as code-sources within the new shared-library.

>ant publish-shared-library
                            Buildfile: D:\myprojects\java\eclipse\workspace\how-to-swapjdbclib\build.xml                             
common:
[echo] BuildName: how-to-swapjdbclib
[echo] BuildHome: D:\myprojects\java\eclipse\workspace\how-to-swapjdbclib
[echo] BuildFile: D:\myprojects\java\eclipse\workspace\how-to-swapjdbclib\build.xml
[echo] BuildJVM: 1.5
[echo] OracleHome: c:\java\oc4j-10131-dev
init:
[echo] -----> Initializing project properties
publish-shared-library:
[oracle:publishSharedLibrary] Publishing shared library oracle.jdbc.
[oracle:publishSharedLibrary] Publish shared library COMPLETES.
BUILD SUCCESSFUL
Total time: 27 seconds

The successful execution of the publish-shared-library target will result in the %ORACLE_HOME%\j2ee\home\config\server.xml containing a new shared library element with defined code-source tags for each archive that was uploaded.

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

The end result of this is that there are now two different versions of the Oracle JDBC driver installed. The default version shipped with the product, and now the additional Oracle JDBC 9.2 version. Applications can now choose between these drivers versions.

Using Application Server Control to Create a Shared Library

With ASC, the Shared Library task located on the Administration page of ASC enables shared libraries to be created, edited and deleted. When creating new shared libraries, ASC allows JAR files from a client to be uploaded directly to the OC4J instance being managed and configured as code-sources for the library.

The format of a shared-library is name/version , where name is the unique name you wish to give to the shared library, and the version is any arbitrary (or meaningful) version string you wish to use. It is possible to install more than one version of a shared-library so the version identifier can be of significance.

When new shared libraries are created and populated with archives, by default they will reside in the following directory structure:

 %ORACLE_HOME%
                          

 \j2ee
                          

 \home
                          

 \shared-lib
                          

 \name
                          

 \version
                          

 archive1.jar
                          

 archive2.jar
                        

For the purposes of this how-to, you will create a new version of the existing oracle.jdbc shared-library, holding the Oracle JDBC 9.2 drivers.

The results of creating the shared library with ASC are visible in the %ORACLE_HOME%\j2ee\home\config\server.xml file. Each shared library is defined with the <shared-library> tag, and each JAR file to be used as a code-source is declared using the <code-source> tag.

1.

Navigate back to the OC4J:Home page

Select the Administration tab.

 
2.

Select the Shared Libraries task to manage the shared libraries.

Click the Create button to create a new Shared Library.

 
3.

Enter the details for the new Shared Library.

Shared Library Name: oracle.jdbc
Shared Library Version: 9.2

Click the Next button.

 
4. Select the Add button to upload an archive.
 
5.

Click the Browse button to open a File Upload dialog.

Using the File Upload dialog, locate the odjcb14.jar file from the Oracle JDBC 9.2 driver

Click the Open button in the File Upload dialog.

 
6. Click the Continue button to upload the archive to the server.
 
7. Click the Finish button to complete the creation of the new Shared Library.
 
8.

Observe that the new Shared Library has been created of the form oracle.jdbc 9.2

 

The %ORACLE_HOME%\j2ee\home\config\server.xml file will now contain a new shared library element with defined code-source tags for each archive that was uploaded.

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

The end result of this is that there are now two different versions of the Oracle JDBC driver installed. The default version shipped with the product, and now the additional Oracle JDBC 9.2 version. Applications can now choose between these drivers versions.

Consuming a Published Shared Library

Once the oracle.jdbc:9.2 shared library has been installed and published, it can then be consumed by any of the applications which are deployed to OC4J.

The shared-library set which is available to an application is determined by two factors.

The first defining factor is the parent application. Since OC4J supports a parent application concept for deployed applications, a newly deployed application will inherit the shared-libraries set from it's specified parent.

In most cases new applications are deployed with the 'default' application being specified as the parent application. This results in the shared-library set which is specified for the default application being inherited by the child application.

The second defining factor is the applications own specific configuration which is defined in the applications own orion-application.xml file. This file allows settings to be applied specifically for the one application, including the supplementing and overriding of inherited properties from it's parent.

Thus configuring a specific shared-library set for an application can be performed by adding shared-library related tags to the applications orion-application.xml.

<imported-shared-libraries>
  <import-shared-library name="library.name" min-version="library.version" max-version="library.version"/>
</imported-shared-libraries>

Class loading behaviour can also be prescribed using ASC during an applications deployment phase. The class loading settings are configurable on the Deployment Tasks page as the final step before performing the deployment via ASC. This ultimately results in the imported-shared-library tags being added to the orion-application.xml file of the application being deployed.

Since we have an existing application that has been deployed via the Ant tasks, we will now use ASC to redeploy the how-to-swapjdbclib application and specify the required version of the Oracle JDBC driver to use.

1.

Select the Applications tab to view the deployed applications.

Select the how-to-swapjdbclib check box.

Click the Redeploy button

 
2.

Click the Browse button to open a File Upload dialog.

Locate the how-to-swapjdbclib.ear file from the how-to directory.

 
3.

Observe the details which are fetched from the server for this redeployment operation.

Click the Next button to proceed.

 
4. Select the Configure Class Loading task from the Deployment Tasks page.
 
5.

This page lists all of the Shared Libraries which are installed on the server.

The application already imports the oracle.jdbc library. We need to specify the version to use.

Specify 9.2 in the Maximum Version to Use column in the oracle.jdbc line.

Click the OK button to continue.

 
6. Click the Redeploy button to proceed with the redeployment operation.
 
7.

Verify the redeployment operation was successful.

Click the Return button to exit the deployment operation.

(Optional) Manual Configuration and Redeployment with Ant

The shared-library dependency can also be configured manually within the application itself and redeployed using Ant.

To do this, edit the ./etc/orion-application.xml, uncomment the following lines and save the file.

  
                           <!-- This is an example of configuring shared-library use for an application -->                             
<!--
<imported-shared-libraries>
<import-shared-library name="oracle.jdbc" max-version="9.2" min-version="9.2"/>
</imported-shared-libraries>
-->

The <import-shared-library> tag defines the version of the oracle.jdbc shared-library to use. Setting the min-version and max-version attributes to a value of "9.2" forces the classloader to supply the oracle.jdbc:9.2 shared-library to the application.

First ensure the oracle.jdbc shared-library has been created using either the Ant publish-shared-library target or by using the shared library task in ASC, then deploy the application using the deploy target.

      >ant deploy

Re-Executing the Application

The how-to-swapjdbclib application has now been redeployed and configured to use the Oracle JDBC 9.2 driver as defined in the oracle.jdbc:9.2 shared-library.

To observe the results of the shared-library change, re-execute the application to view the JDBC driver version it displays.

                            http://localhost:8888/how-to-swapjdbclib
                        

A correctly configured server will now show

“The JDBC driver loaded is : Oracle JDBC driver version 9.2.0.5.0”

Where the version will match the version of the Oracle JDBC driver you downloaded and configured as a new oracle.jdbc shared-library.

Note: if the ./lib/ojdbc14.jar library was used, the version string will show as 9.2.0.4.0.

The HTML page in the browser should look like the below:

 

Summary

This how-to has demonstrated the ability to provide an alternative JDBC driver version and configure applications to make use of it.

The choice of which libraries an application uses is now yours.

Left Curve
Popular Downloads
Right Curve
Untitled Document