How to setup Connection Pooling usinig Apache/Tomcat
I first create the Global Naming Resources - references to the databases - in the $CATALINA_HOME/conf/server.xml configuration file. You will want to place these references within the GlobalNamingResources attribute tag:
<Resource name="jdbc/TestMySQL"
auth="Container"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
type="javax.sql.DataSource"
driverClassName="org.gjt.mm.mysql.Driver"
url="jdbc:mysql://localhost:3307/mysql?autoReconnect=true"
username="root"
password="password"
maxActive="100"
maxIdle="20"
maxWait="1000"
removeAbandoned="true"
logAbandoned="true"
removeAbandonedTimeout="30"
/>
<Resource name="jdbc/TestOracle"
auth="Container"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)(ADDRESS=(PRO
TOCOL=TCP)(HOST=rac1-vip)(PORT=1525))(ADDRESS=(PROTOCOL=TCP)(HOST=rac2-vip)(PORT
=1525))(CONNECT_DATA=(SERVICE_NAME=jlc.colestock.test)))"
username="test"
password="password"
maxActive="100"
maxIdle="20"
maxWait="1000"
removeAbandoned="true"
logAbandoned="true"
removeAbandonedTimeout="30"
/>
As you can see I have added an entry for a MySQL database as well as an Oracle Clustered Database. If following this example, you will want to replace any applicable values with those specific to your environment.
In order to make the aformentioned resources available via the specified JDBC Drivers, the database-specific jars need to be added to $CATALINA_HOME/common/lib. In my case:
For MySQL:
# ls -1 /var/lib/apache-tomcat/common/lib/mysql-connector-java-5.1.5-bin.jar
/var/lib/apache-tomcat/common/lib/mysql-connector-java-5.1.5-bin.jar
For Oracle:
# ls -1 $CATALINA_HOME/common/lib/ojdbc5.jar
/var/lib/apache-tomcat/common/lib/ojdbc5.jar
After performing these steps, you should restart Tomcat per your pre-established process.
Next, I create a Java web application for each data source to test their respective connection pool. Note that these are simply test apps and aren't production-ready example that use proper design patterns and so forth.
Here is the source code for the test web applications, named mysqlcp and oraclecp:
mysqlcp.tar
oraclecp.tar
mysqlcp.tar
mysqlcp/
mysqlcp/docs/
mysqlcp/classes/
mysqlcp/lib/
mysqlcp/src/
mysqlcp/src/com/
mysqlcp/src/com/example/
mysqlcp/src/com/example/TestMySQL.java
mysqlcp/web/
mysqlcp/web/testmysql.jsp
mysqlcp/etc/
mysqlcp/etc/web.xml
mysqlcp/etc/context.xml
mysqlcp/build.xml
mysqlcp/build/
mysqlcp/build/WEB-INF/
mysqlcp/build/WEB-INF/web.xml
mysqlcp/build/WEB-INF/classes/
mysqlcp/build/WEB-INF/classes/com/
mysqlcp/build/WEB-INF/classes/com/example/
mysqlcp/build/WEB-INF/classes/com/example/TestMySQL.class
mysqlcp/build/WEB-INF/lib/
mysqlcp/build/META-INF/
mysqlcp/build/META-INF/context.xml
mysqlcp/build/testmysql.jsp
mysqlcp/dist/
mysqlcp/dist/docs/
mysqlcp/dist/mysqlcp.war
mysqlcp/build.properties
oraclecp.tar
oraclecp/
oraclecp/docs/
oraclecp/classes/
oraclecp/lib/
oraclecp/src/
oraclecp/src/com/
oraclecp/src/com/example/
oraclecp/src/com/example/TestOracle.java
oraclecp/web/
oraclecp/web/testoracle.jsp
oraclecp/etc/
oraclecp/etc/web.xml
oraclecp/etc/context.xml
oraclecp/build.xml
oraclecp/build/
oraclecp/build/testoracle.jsp
oraclecp/build/WEB-INF/
oraclecp/build/WEB-INF/web.xml
oraclecp/build/WEB-INF/classes/
oraclecp/build/WEB-INF/classes/com/
oraclecp/build/WEB-INF/classes/com/example/
oraclecp/build/WEB-INF/classes/com/example/TestOracle.class
oraclecp/build/WEB-INF/lib/
oraclecp/build/META-INF/
oraclecp/build/META-INF/context.xml
oraclecp/dist/
oraclecp/dist/docs/
oraclecp/dist/oraclecp.war
oraclecp/build.properties
Each test application consists of a test connection class, a test jsp, as well as the requisite configuration files.
The applications' war files contain a context.xml configuration file, referencing the global resources put in server.xml; for example in the oraclecp.war:
<Context path="/oraclecp" docBase="oraclecp" debug="5" reloadable="true">
<ResourceLink global="jdbc/TestOracle" name="jdbc/TestOracle" type="javax.sql.Da
taSource"/>
In order to test these applications, simply unpack them and copy the war files to $CATALINA_HOME/webapps/. Tomcat will automcatically deploy both each application as well as its context, etc.
Once each application is deployed, call its test .jsp page. For MySQL, it should return a page listing the distinct names of users in mysql.user:

For Oracle, it should return a page listing the distinct names of users in sys.dba_users:

Labels: Application Servers, JAVA
How to Install Apache Tomcat on Linux
Download and install the Java SDK compatible with your Tomcat version, for me: JDK 5.0
# mv jdk-1_5_0_15-nb-6_0_1-linux-ml.sh /var/lib/.
# cd /var/lib
# chmod u+x jdk-1_5_0_15-nb-6_0_1-linux-ml.sh
# export DISPLAY=192.168.1.2:0.0
# ./jdk-1_5_0_15-nb-6_0_1-linux-ml.sh
I install the version that comes with the NetBeans GUI, so I simply export
my DISPLAY, execute the script, and follow the installation wizard's prompts.
Afterwards, I create symbolic links as appropriate:
# ln -sf jdk1.5.0_15 java
# cd /usr/bin
# ln -sf /var/lib/java/bin/java java
# ln -sf /var/lib/java/bin/javac javac
# ln -sf /var/lib/java/bin/javadoc javadoc
# ln -sf /var/lib/java/bin/javah javah
Download and install Apache Tomcat, I will be installing Apache Tomcat 5.5.26
Create a User for tomcat:
# useradd tomcat
# usermod -g tomcat tomcat
# passwd tomcat
Extract binaries, change ownership, create symbolic links:
# tar xvfz apache-tomcat-5.5.26.tar.gz -C /var/lib/
# chown -R tomcat:tomcat apache-tomcat-5.5.26
# ln -sf apache-tomcat-5.5.26 apache-tomcat
Edit the tomcat user's .bash_profile, adding the following lines (Note: Ant will be installed later in this section):
export JAVA_HOME=/var/lib/java
export CATALINA_HOME=/var/lib/apache-tomcat
export ANT_HOME=/var/lib/apache-ant
export PATH=$JAVA_HOME/bin:$ANT_HOME/bin:$PATH
Build jsvc in order to run
Apache Tomcat as a service:
# su - tomcat
# cd $CATALINA_HOME/bin
# tar xvfz jsvc.tar.gz
# autoconf
# chmod u+x configure
# ./configure
# make
# cp jsvc ..
Install the following tomcat startup file to /etc/init.d/tomcat and edit as appropriate:
# chkconfig: 345 64 36
# description: Start Tomcat
#!/bin/sh
JAVA_HOME=/var/lib/java
CATALINA_HOME=/var/lib/apache-tomcat
DAEMON_HOME=/var/lib/apache-tomcat
TOMCAT_USER=tomcat
# for multi instances adapt those lines.
TMP_DIR=/var/tmp
PID_FILE=/var/run/jsvc.pid
CATALINA_BASE=/var/lib/apache-tomcat
CATALINA_OPTS="-Xms48m -Xmx256M"
CLASSPATH=\
$JAVA_HOME/lib/tools.jar:\
$CATALINA_HOME/bin/commons-daemon.jar:\
$CATALINA_HOME/bin/bootstrap.jar
case "$1" in
start)
#
# Start Tomcat
#
$DAEMON_HOME/bin/jsvc \
-user $TOMCAT_USER \
-home $JAVA_HOME \
-Dcatalina.home=$CATALINA_HOME \
-Dcatalina.base=$CATALINA_BASE \
-Djava.io.tmpdir=$TMP_DIR \
-wait 10 \
-pidfile $PID_FILE \
-outfile $CATALINA_HOME/logs/catalina.out \
-errfile '&1' \
$CATALINA_OPTS \
-cp $CLASSPATH \
org.apache.catalina.startup.Bootstrap
#
# To get a verbose JVM
#-verbose \
# To get a debug of jsvc.
#-debug \
exit $?
;;
stop)
#
# Stop Tomcat
#
$DAEMON_HOME/bin/jsvc \
-stop \
-pidfile $PID_FILE \
org.apache.catalina.startup.Bootstrap
exit $?
;;
*)
echo "Usage tomcat.sh start/stop"
exit 1;;
esac
Configure the service via chkconfig and start:
# chkconfig --add tomcat
# chkconfig --list tomcat
tomcat 0:off 1:off 2:off 3:on 4:on 5:on 6:off
# service tomcat start
Configure Tomcat to allow use of the 'manager' application:
# vi $CATALINA_HOME/conf/tomcat-users.xml
Add the 'manager' role and a user of your choosing whom will be assigned this role:
<role rolename="manager"/>
<user username="admin" password="admin" roles="manager"/>
Test Apache Tomcat by trying any of the various test URLs, including the manager application:



Download and Install Ant from a binary distribution of Ant
# tar xvfz apache-ant-1.7.0-bin.tar.gz -C /var/lib
# cd /var/lib
# ln -sf apache-ant-1.7.0/ apache-ant
Copy the required library to the Ant binaries:
# export CATALINA_HOME=/var/lib/apache-tomcat
# export ANT_HOME=/var/lib/apache-ant
# cp $CATALINA_HOME/server/lib/catalina-ant.jar $ANT_HOME/lib/.
Test the functionality of Ant by downloading and extracting this test application:
# cd /home/tomcat
# tar xvfz test.tar.gz
test/
test/docs/
test/src/
test/src/Test.java
test/web/
test/web/WEB-INF/
test/web/WEB-INF/test.xml
test/web/WEB-INF/web.xml
test/build.xml
test/build.properties
Test Ant by creating a distribution and deploying it to $CATALINA_HOME/webapps:
# cd /home/tomcat/test
# ant dist
Buildfile: build.xml
prepare:
[mkdir] Created dir: /home/tomcat/test/build
[mkdir] Created dir: /home/tomcat/test/build/WEB-INF
[mkdir] Created dir: /home/tomcat/test/build/WEB-INF/classes
[copy] Copying 2 files to /home/tomcat/test/build
[mkdir] Created dir: /home/tomcat/test/build/WEB-INF/lib
compile:
[javac] Compiling 1 source file to /home/tomcat/test/build/WEB-INF/classes
dist:
[mkdir] Created dir: /home/tomcat/test/dist/docs
[jar] Building jar: /home/tomcat/test/dist/test.war
BUILD SUCCESSFUL
Total time: 1 second
# cp ./dist/*.war $CATALINA_HOME/webapps/.
Test the deployment via:

Integrate Tomcat with existing Apache installation
Download the mod_jk that corresponds to your Apache version: mod_jk-1.2.26-httpd-2.0.61.so
# cd /usr/sbin/
# ./httpd -version
Server version: Apache/2.0.52
Server built: Mar 19 2007 12:13:18
Move the .so library to the Apache modules directory:
# mv mod_jk-1.2.26-httpd-2.0.61.so /etc/httpd/modules/mod_jk.so
Create the workers.properties configuration file that will be used by the connector:
# cd $CATALINA_HOME/conf
# vi workers.properties
workers.properties
workers.tomcat_home=/var/lib/apache-tomcat
workers.java_home=/var/lib/java
ps=/
worker.list=ajp13
worker.ajp13.port=8009
worker.ajp13.host=localhost
worker.ajp13.type=ajp13
Edit the httpd.conf to include this module along with corresponding directives:
# cd /etc/httpd/conf
# vi httpd.conf
Add the following lines:
LoadModule jk_module modules/mod_jk.so
JkWorkersFile /var/lib/apache-tomcat/conf/workers.properties
JkLogFile /etc/httpd/logs/mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JKMount /*.do ajp13
JKMount /*.jsp ajp13
Reload or stop Apache Service:
# service httpd start
Starting httpd: [ OK ]
Test the Connector by requesting the test application using Apache instead of Tomcat. If everything is working properly, Apache will hand off the request to Tomcat:

If successful, you have a working Apache Tomcat development environment.
Labels: Application Servers, JAVA
Connecting to MySQL via MySQL Connector/J
The following is a sample Java class that utilizes the JDBC driver that comes with MySQL Connector/J. Of course this is just a sample class, which you can edit and compile to verify the efficacy of your installation. This does not represent production-ready code.
Download the Connector/J software
MySQL Connector/J Software Downloads 5.1
Gunzip and untar the distribution, extracting the following jar to the location of your choice:
# ls -1 /opt/mysql/*jar
/opt/mysql/mysql-connector-java-5.1.5-bin.jar
As you can see, after the gunzip and untar, I have opted to place the aforementioned jar file in /opt/mysql
Edit the following class, altering the connection information and the query it executes as appropriate:
MySQLJTest.java
import java.io.*;
import java.sql.*;
public class MySQLJTest {
public static void main (String args[]){
Statement stmt = null;
ResultSet rs = null ;
Connection conn = null;
System.out.println("Beginning Test of MySQL Connector J");
System.out.println("Loading Driver...");
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (Exception e) {
System.out.println("Exception Loading MySQL Connector J Driver");
e.printStackTrace();
}
System.out.println("Obtaining Connection...");
try {
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3307/mysql?" + "user=oracle&password=password");
} catch (SQLException se) {
System.out.println("SQLException: " + se.getMessage());
System.out.println("VendorError: " + se.getErrorCode());
}
System.out.println("Testing Connection with a query...");
try { stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT User, Host, Password from user");
System.out.println("Processing the ResultSet...");
while (rs.next()) {
System.out.println(rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3) + "\n");
}
} catch (SQLException se) {
System.out.println("SQLException: " + se.getMessage());
System.out.println("VendorError: " + se.getErrorCode());
} finally {
if (rs != null) {
try { rs.close();
} catch (SQLException se) { }
rs = null;
}
if (stmt != null) {
try { stmt.close();
} catch (SQLException se) { }
stmt = null;
}
} //Ends Finally
} //Ends Main Method
} //Ends Class Definition
After editing, you can use the following script to compile and run the program. Since, I am a heavy Oracle user, I have chosen to use the Java JDK that is in the databases' software home - you will want to modify the following script to account for the location of your JDK:
MySQLJTest.bsh
#!/bin/bash
JAVA_HOME=/u03/app/oracle/product/db/11.1.0.6/jdk
CLASSPATH=/opt/mysql/mysql-connector-java-5.1.5-bin.jar:.:$JAVA_HOME/jre/lib:$CLASSPATH
$JAVA_HOME/bin/javac -classpath $CLASSPATH MySQLJTest.java
$JAVA_HOME/jre/bin/java -version
$JAVA_HOME/jre/bin/java -classpath $CLASSPATH MySQLJTest
Once you have edited the scripts as appropriate, you can run the aforementioned script to compile and run the program:
# ./MySQLJTest.bsh
java version "1.5.0_11"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_11-b03)
Java HotSpot(TM) Client VM (build 1.5.0_11-b03, mixed mode)
Beginning Test of MySQL Connector J
Loading Driver...
Obtaining Connection...
Testing Connection with a query...
Processing the ResultSet...
root localhost 5d2e19393cc5ef67
root rac2.colestock.test 5d2e19393cc5ef67
root 127.0.0.1 5d2e19393cc5ef67
oracle rac2.colestock.com 5d2e19393cc5ef67
oracle localhost 5d2e19393cc5ef67
oracle 192.168.1.104 5d2e19393cc5ef67
oracle 127.0.0.1 5d2e19393cc5ef67
If successful, you should have output similar to mine.
Here are the source files from this posting: MySQLJTest.tar
11g New Feature: (DRCP) Database Resident Connection Pooling
A great overview of this new feature can be found in this excellent article:
Oracle Database 11g:
The Top New Features for DBAs and Developers
by Arup Nanda: Caching and Pooling
I followed Arup's example, and just extended upon it:
Here is the tnsnames.ora entry I created just for connections that are going to use the database resident connection pool (DRCP):
[/u03/app/oracle/product/db/11g/network/admin cubs2@rac2]$ tail -19 tnsnames.ora
CUBS_POOL.COLESTOCK.TEST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1522))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1522))
(LOAD_BALANCE = yes)
)
(CONNECT_DATA =
(SERVER = POOLED)
(SERVICE_NAME = cubs.colestock.test)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 180)
(DELAY = 5)
)
)
)
Of course, I did this on both of my instances.
Next, I cut and pasted Arup's Java class and modified it for my purposes:
[/tmp cubs2@rac2]$ more CacheTest.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class CacheTest {
private String jdbcURL = "jdbc:oracle:oci8:@CUBS_POOL";
private Connection conn = null;
public CacheTest( ) throws ClassNotFoundException {
Class.forName("oracle.jdbc.driver.OracleDriver");
}
public static void main(String[] args) throws ClassNotFoundException, SQLException {
CacheTest check = new CacheTest();
check.dbconnect();
check.doSomething();
}
public void dbconnect() throws SQLException {
System.out.println("Connecting with URL="+jdbcURL+" as scott/tiger");
try {
conn = DriverManager.getConnection( jdbcURL, "scott" , "tiger");
System.out.println("Connected to Database");
} catch (SQLException sqlEx) {
System.out.println(" Error connecting to database : " + sqlEx.toString());
}
}
public void doSomething() throws SQLException {
Statement stmt = null;
ResultSet rset = null;
try {
stmt = conn.createStatement();
System.out.println("Created Statement object");
rset = stmt.executeQuery("select /*+ result_cache */ count(*) from scott.dept");
System.out.println("Retrieved ResultSet object");
if(rset.next())
System.out.println("Result:"+rset.getString(1));
} catch (SQLException sqlEx) {
} finally {
try {
System.out.println("Closing Statment & ResultSet Objects");
if (rset != null) rset.close();
if (stmt != null) stmt.close();
if (conn != null) {
System.out.println("Disconnecting...");
conn.close();
System.out.println("Disconnected from Database");
}
} catch (Exception e) { }
}
}
}
Then I compiled it:
[/tmp cubs2@rac2]$ export ORACLE_SID=cubs2
[/tmp cubs2@rac2]$ . oraenv
The Oracle base for ORACLE_HOME=/u03/app/oracle/product/db/11g is /u03/app/oracle
[/tmp cubs2@rac2]$ $ORACLE_HOME/jdk/bin/javac -verbose -classpath .:$ORACLE_HOME/jdbc/lib/jodbc5.jar CacheTest.java
[parsing started CacheTest.java]
[parsing completed 52ms]
[search path for source files: [.]]
[search path for class files: [/u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar, /u03/app/oracle/product/db/11g/jdk/jre/lib/jsse.jar, /u03/app/oracle/product/db/11g/jdk/jre/lib/jce.jar, /u03/app/oracle/product/db/11g/jdk/jre/lib/charsets.jar, /u03/app/oracle/product/db/11g/jdk/jre/lib/ext/localedata.jar, /u03/app/oracle/product/db/11g/jdk/jre/lib/ext/sunjce_provider.jar, /u03/app/oracle/product/db/11g/jdk/jre/lib/ext/sunpkcs11.jar, /u03/app/oracle/product/db/11g/jdk/jre/lib/ext/dnsns.jar, .]]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/sql/Connection.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/sql/DriverManager.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/sql/ResultSet.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/sql/SQLException.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/sql/Statement.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/Object.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/String.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/ClassNotFoundException.class)]
[checking CacheTest]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/Exception.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/Throwable.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/Class.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/System.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/io/PrintStream.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/io/FilterOutputStream.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/io/OutputStream.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/util/Properties.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/Error.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/RuntimeException.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/StringBuilder.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/AbstractStringBuilder.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/CharSequence.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/io/Serializable.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/Comparable.class)]
[loading /u03/app/oracle/product/db/11g/jdk/jre/lib/rt.jar(java/lang/StringBuffer.class)]
[wrote CacheTest.class]
[total 423ms]
Now, the sample Java Class is ready to go. I created a wrapper script which calls this Class from a bash while loop:
[/tmp cubs2@rac2]$ more run_CacheTest.bsh
#!/bin/bash
export ORACLE_SID=cubs2;
. oraenv ;
while true
do
$ORACLE_HOME/jdk/bin/java -classpath /tmp/:.:$ORACLE_HOME/jdbc/lib/ojdbc5.jar CacheTest
done
Next, we have to start the default connection pool:
SQL> exec dbms_connection_pool.start_pool;
PL/SQL procedure successfully completed.
I placed one on these scripts on each of my database hosts and adjusted the $ORACLE_SID value as appropriate. I will call many instances of this script (using nohup to the background) from each database server to perform a load test; for example:
[/tmp cubs1@rac1]$ nohup /tmp/run_CacheTest.bsh &
[5] 24453
nohup: [/tmp cubs1@rac1]$ appending output to `nohup.out'
The combination of the DRCP as well as the results cache, should allow me to scale well beyond prior limits.
Here are the some of the results:
As you can see, I am simply using the default connection pool:
SQL> select pool_name, inst_id, num_open_servers, num_busy_servers, num_requests, num_waits, historic_max, num_purged from gv$cpool_stats;
POOL_NAME INST_ID NUM_OPEN_SERVERS NUM_BUSY_SERVERS NUM_REQUESTS NUM_WAITS HISTORIC_MAX NUM_PURGED
------------------------------ ---------- ---------------- ---------------- ------------ ---------- ------------ ----------
SYS_DEFAULT_CONNECTION_POOL 1 14 2 2448 0 14 0
SYS_DEFAULT_CONNECTION_POOL 2 10 1 562 0 10 0
Note the high 'Find Count' for each instance:
SQL> select * from gv$result_cache_statistics order by name, inst_id;
INST_ID ID NAME VALUE
---------- ---------- ---------------------------------------- ----------
1 3 Block Count Current 32
2 3 Block Count Current 32
1 2 Block Count Maximum 1728
2 2 Block Count Maximum 1728
1 1 Block Size (Bytes) 1024
2 1 Block Size (Bytes) 1024
1 6 Create Count Failure 0
2 6 Create Count Failure 0
1 5 Create Count Success 1
2 5 Create Count Success 3
1 9 Delete Count Invalid 0
2 9 Delete Count Invalid 0
1 10 Delete Count Valid 0
2 10 Delete Count Valid 0
1 7 Find Count 3426
2 7 Find Count 1292
1 8 Invalidation Count 0
2 8 Invalidation Count 0
1 4 Result Size Maximum (Blocks) 86
2 4 Result Size Maximum (Blocks) 86
As you can see, I was able to perform over a thousand executions on the cluster with virtual no I/O over an 11-minute period:
select * from
2 (select instance_number, executions_total - lag(executions_total,1) over (order by instance_number, snap_id) "EXECUTIONS_TOTAL",snap_id
3 from dba_hist_sqlstat
4 where sql_id='1gy9qq7yjm054')
5 where snap_id=96;
INSTANCE_NUMBER EXECUTIONS_TOTAL SNAP_ID
--------------- ---------------- ----------
1 662 96
2 529 96
Here are the AWR reports from the test (both instances) - notice the efficiency:
CUBS1 Instance AWR Report
CUBS2 Instance AWR Report
How to Setup Oracle Connection Pooling with Oracle Application Server 10g using JNDI/JDBC
Assumptions:
A compatible JDK is already installed and included in your path. Likewise, it is assumed that %JAVA_HOME% is set and resides within your permanent System environment %PATH%. I used the JDK that came with JDeveloper for both the development and as the JDK the Standalone Oracle Application Server uses.
Setting up the Example:
Download Oracle Application Server Containers for J2EE Standalone from Oracle - I used version 10.1.3.0.0, build#060119.
Install Oracle Application Server Containers for J2EE Standalone by
referencing the Standalone User's Guide: Standalone User's Guide. Instead of relying upon the official documentation for the installation, I read the readme.txt file immediate after unzipping the distribution for detailed, distribution-specific installation information.
In my case (adjust accordingly for path differences, etc.):
mkdir c:\oc4j_standalone
cd c:\oc4j_standalone
unzip c:\temp\oc4j_extended_101300.zip
set JAVA_HOME=c:\jdev10g\jdk
set ORACLE_HOME=c:\oc4j_standalone
set PATH=%JAVA_HOME%\bin;%ORACLE_HOME%\bin;%PATH%
oc4j -start
You will receive the following prompt at the command line; enter and confirm password when prompted:
Enter password: ********
Confirm password: ********
Confirm password: The password for OC4J administrator "oc4jadmin" has been set.
06/03/07 15:08:59 The OC4J administrator "oc4jadmin" account is activated.
2006-03-07 15:09:11.959 NOTIFICATION JMS Router is initiating ...
06/03/07 15:09:14 Oracle Containers for J2EE 10g (10.1.3.0.0) initialized
Visit the index page -- in my case, http://localhost:8888/ -- to verify that the Standalone Application Server is functioning.
I created a test application using JDeveloper - first_j2ee - that can be used to validate your set-up (Note: Right-click 'Save Target As'):
Source ¦ first_j2ee.ear
Deploy the Sample Application via (adjust -file and password values as appropriate):
set ORACLE_HOME=c:\oc4j_standalone
set PATH=%ORACLE_HOME%\bin;%PATH%
cd j2ee
cd home
java -jar admin.jar ormi://localhost:23791 oc4jadmin password -deploy -file c:/temp/first_j2ee.ear -deploymentName first_j2ee
[ 2006-03-13 10:03:51.625 PST ] Application Deployer for first_j2ee STARTS.
[ 2006-03-13 10:03:51.672 PST ] Copy the archive to C:\oc4j_standalone\j2ee\home
\applications\first_j2ee.ear
[ 2006-03-13 10:03:51.719 PST ] Initialize C:\oc4j_standalone\j2ee\home\applications\first_j2ee.ear begins...
[ 2006-03-13 10:03:51.719 PST ] Unpacking first_j2ee.ear
[ 2006-03-13 10:03:51.812 PST ] Done unpacking first_j2ee.ear
[ 2006-03-13 10:03:51.812 PST ] Unpacking first_j2ee.war
[ 2006-03-13 10:03:51.922 PST ] Done unpacking first_j2ee.war
[ 2006-03-13 10:03:51.938 PST ] Initialize C:\oc4j_standalone\j2ee\home\applications\first_j2ee.ear ends...
[ 2006-03-13 10:03:51.938 PST ] Starting application : first_j2ee
[ 2006-03-13 10:03:51.938 PST ] Initializing ClassLoader(s)
[ 2006-03-13 10:03:51.938 PST ] Initializing EJB container
[ 2006-03-13 10:03:51.938 PST ] Loading connector(s)
[ 2006-03-13 10:03:52.219 PST ] Starting up resource adapters
[ 2006-03-13 10:03:52.219 PST ] Initializing EJB sessions
[ 2006-03-13 10:03:52.219 PST ] Committing ClassLoader(s)
[ 2006-03-13 10:03:52.219 PST ] Initialize first_j2ee begins...
[ 2006-03-13 10:03:52.234 PST ] Initialize first_j2ee ends...
[ 2006-03-13 10:03:52.234 PST ] Started application : first_j2ee
[ 2006-03-13 10:03:52.250 PST ] Application Deployer for first_j2ee COMPLETES. O peration time: 625 msecs
Next, bind the Sample Application:
java -jar admin.jar ormi://localhost:23791 oc4jadmin password -bindwebapp first_j2ee first_j2ee default-web-site /first_j2ee
Load the Static HTML Page in order to verify successful deployment and subsequent binding. The body of the page should read: 'The first_j2ee application has been deployed successfully!'.
I have packaged along with the application's source, the data-sources.xml file that you need to move and edit in order to accomplish this.
Extract and move the data-sources.xml file to your %ORACLE_HOME%\j2ee\home\application-deployments\first_j2ee directory. This is the *.xml file that defines the connection pool resource, etc. Modify the following elements/attributes for your environment:
- url - to reflect your database service
- username - to reflect the username you want to connect with (must have select on v$instance for this example to work)
- password - to reflect the password for the aforementioned username
Once the aforementioned modificaions have been made, test via: http://localhost:8888/first_j2ee/TestJNDI. If successful, the page will return the value of the instance and host name for the database service you specified in data-sources.xml.
Labels: Application Servers, JAVA
How to Setup Oracle Connection Pooling with Apache Tomcat using JNDI/JDBC
In order to create truly scalable web applications that leverage a RDBMS, the use of connection-pooling is critical. Setting this up can be a daunting task since every application server/container combination is configured using slightly different methods. Current J2EE standards don't require truly universal server configuration files, deployment, etc. Throw into the mix JNDI (so that you don't have to hard-code authentication information, etc.); JDBC; Oracle, etc. and you can have a real head-scratcher on your hands. Adequate, comprehensive documentation that illustrates how to set this up from end-to-end is virtually non-existent - the vendors really do a poor job. The following example focuses on Apache/Tomcat against Oracle 8i or higher.
Assumptions:
- You have an existing Oracle database and listener (in my case, a local database named repo.colestock.com)
- You are using an adequately powered machine with a supported Windows O/S
Download and install a Java 2 SDK (Software Development Kit - not just the runtime!) compatible with your desired Apache/Tomcat release. In my example, I will be installing Apache/Tomcat 5.0.28, therefore I will be using Java SDK 1.4.2.11 - the most recent 1.4.X release at the time of this post:
http://java.sun.com/j2se/1.4.2/download.html
Choose the 'Windows Offline Installation' option, downloading the relevant *.exe.
Launch the installer *.exe and follow the prompts to install the SDK (annotate the install location - this will later become your %JAVA_HOME%)
Set the %JAVA_HOME% system environment variable by navigating to:
Start > Control Panel > System > Advanced (Environment Variables) and creating a new system variable named 'JAVA_HOME' and provide the path of the SDK location as its value (Example: 'C:\j2sdk1.4.2_11'). After words, add %JAVA_HOME%\bin to the front of the system's %PATH% variable. Apache/Tomcat will now be able to use your Java installation.
Download, unzip, and install the desired Apache/Tomcat version from http://tomcat.apache.org/download-55.cgi (I chose the *.zip associated with the 5.0.28 release). When installing, I normally perform a custom install and select the 'Service' option under the 'Tomcat' heading. Annotate the directory location in which you installed the software (i.e. %CATALINA_HOME%) as well as the password you provided for 'Administrator Login'.
After you have installed Tomcat, ensure that it is running by visiting the default page at: http://localhost:8080/. If Tomcat is not running, start the service via the command-line: net start "Apache Tomcat" (or via any other method you prefer).
The next step is to place the required *.jar files that include the Oracle JDBC drivers and other database libraries into the %CATALINA_HOME%\common\lib directory. Doing this makes the libraries globally available to all application as well as the server itself. Copy the following libraries from your %ORACLE_HOME%\jdbc\lib directory to %CATALINA_HOME%\common\lib:
- ojdbc14.jar
After doing so, cycle Tomcat via your preferred method.
I created a test application using Ant - called first_j2ee - that can be used to validate your set-up (Note: Right-click 'Save Target As'):
Source ¦ first_j2ee.war
Save the *.war file to your local machine (renaming as necessary back to first_j2ee.war). The source is provided, just in case you want to get a closer look and/or if you wish to use it as the basis for your own test application - remember to edit the path information in the build.xml file, should you choose to use this code tree.
Tomcat includes a handy function, that automatically deploys any *.war file dropped in its %CATALINA_HOME%\webapps directory - this is how we will deploy our test application.
Copy first_j2ee.war to your %CATALINA_HOME%\webapps directory (Example: C:\Tomcat5.0\webapps).
Test that the application was deployed via http://localhost:8080/first_j2ee/test.html. A successful deployment will return the following String in the body: "The first_j2ee application has been deployed successfully!". Nothing fancy, granted, but you get the picture.
Now comes the tough part. We need to define in the application's context a connection pool resource and a resource reference to it. This will allow our test Servlet to lookup and obtain an Oracle database connection from an Application Server-managed connection pool. I have packaged along with the application's *.war file, the *.xml file that you need to move and edit in order to accomplish this.
Start by moving the %CATALINA_HOME%\webapps\WEB-INF\first_j2ee.xml file to the %CATALINA_HOME%\conf\Catalina\localhost directory. This is the *.xml file that defines the connection pool resource, etc. Modify the following elements/attributes for your environment:
- url - to reflect your database service
- username - to reflect the username you want to connect with (must have select on v$instance for this example to work)
- password - to reflect the password for the aforementioned username
- docBase attribute of Context - to reflect the directory path considering your %CATALINA_HOME%
Once the aforementioned modificaions have been made, test via: http://localhost:8080/first_j2ee/TestJNDI. If successful, the page will return the value of the instance and host name for the database service you specified in first_j2ee.xml.
If you have been successful thusfar, then you can work on tweaking/testing other connection pool directives as desired - the example connection pool does not have settings intended for a production environment.
Labels: Application Servers, JAVA
How to Manually Deploy a WAR using OC4J (UNIX)
Labels: Application Servers, JAVA
