We use Tomcat with Apache HTTPD in our company. And as a database backend, we use a two node Oracle Real Application Cluster (RAC).

We were having stale connection problems when a RAC node was behaving abnormally, because the JDBC pool which was created by Tomcat was not getting any notification about it. So I started searching for a way to take advantage of Oracle’s Fast Connection Failover (FCF) mechanism. FCF is superior to Transparent Application Failover (TAF) as it is event based and supports load balancing across the RAC nodes. It is also superior to having no failover mechanism whatsoever. 🙂

FCF leverages Oracle Notification Service (ONS) to get information about database events. With the help of ONS, a JDBC pool which has FCF enabled can see if a RAC node is up or down and can act accordingly. To be able to use the method I am about to show, you will have to have a minimum Oracle RAC version of 10.2.0, because Oracle versions prior to that do not support “Remote ONS”, which is an essential part of this configuration.

To have a working Oracle connection pool in your Tomcat server, first you must have the necessary JAR files in your Tomcat classpath. Also you must use the appropriate JAR files for your JVM. If you are using Java SDK 1.5 or 1.6, you will have to get the JAR files from Oracle Client or above. If you don’t use the appropriate JAR files with your JVM, you will most probably have severe problems. Pick one of the following configurations:

  • Java SDK 1.4: ojdbc14.jar and ons.jar from Oracle client or above
  • Java SDK 1.5: ojdbc5.jar and ons.jar from Oracle client or above
  • Java SDK 1.6: ojdbc6.jar and ons.jar from Oracle client or above

I am using Tomcat 6.0.20 and Java SDK 1.6 as of this writing. And I have ojdbc6.jar and ons.jar from Oracle client

Copy these two JAR files to /common/lib directory of your Tomcat server. If one of these files does not exist in your environment, your pool will not work.

Now, create a file named ons.config in the directory $ORACLE_HOME/opmn/conf/ and add the following to that file:


You will override the settings written in this file in the JDBC Pool in your server.xml file. Oracle just needs to see this file to get Remote ONS working in Tomcat.

Add the following to your Tomcat startup script:

export ORACLE_HOME="Path to your Oracle Home Directory"
export CATALINA_OPTS="$CATALINA_OPTS -Doracle.ons.oraclehome=$ORACLE_HOME"

Now your environment is complete. To get FCF working, you have to create a special JDBC pool in your server.xml. You can create the pool in both GlobalNamingResources or your web application’s own context. The advantage of creating the pool globally gives you the ability to use the connection in every web application defined in your Tomcat server. I will create the pool globally in this example.

Edit your server.xml and add the following into GlobalNamingResources:

<Resource name="JDBC/Pool" auth="Container"
 description="FCF Datasource"
 connectionCacheProperties="(InitialLimit=5, MinLimit=5, MaxLimit=20, ConnectionWaitTimeout=30)"
 user="username" password="password"
 url="jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1521))(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1521))(LOAD_BALANCE = yes)(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = SERVICE)))"

Let’s explain the important directives in this configuration:

  • name: The name of the pool to be used when getting a connection from it.
  • ONSConfiguration: Remote ONS configuration which is used for getting notifications from the RAC. Important: The IP addresses or hostnames to use here should point to the main IP addresses of the RAC nodes, not the VIP addresses.
  • fastConnectionFailoverEnabled: Enable FCF mechanism.
  • implicitCachingEnabled: Enable implicit caching. This is a requirement of FCF, without implicit caching, FCF will not work.
  • connectionCacheProperties: Here, you can set the connection cache limits. To get a thorough explanation of these variables, refer to Implicit Connection Caching Page at Oracle.
  • connectionCacheName: The name of the cache. If you don’t set a name, Oracle will create a unique name everytime the cache is created, which is not recommended. Also if you create more than one JDBC pool (for example, if you have two user schemas to connect on Oracle) be sure to give a unique name for each of those pools, because this name is used on server side (database side).
  • url: Be careful to use the VIP addresses of RAC nodes in your url, not the main IP addresses.

For all web applications to see the newly created pool, you can add the following to the global context.xml of your Tomcat server:

<ResourceLink global="JDBC/Pool" name="JDBC/Pool"/>

Restart your Tomcat server and you are done. You now have a FCF enabled JDBC pool. I suggest you to read the following documents thoroughly:

Fast Connection Failover
Implicit Connection Caching