Friday, January 18, 2008

Creating a connection pool for Tomcat using Oracle driver

There are lot of documentation and various implementation of connection pool APIs floating around the web for JDBC drivers. Apache has a DBCP API that can be used with almost any JDBC driver.

But I was in a situation were I needed to have a Connection Pool with a non open source product for a standalone java application. Since our database vendor was Oracle; I was looking for a solution from Oracle itself.

When I searched internet; it came up with different APIs by oracle for implementing the connection pool, like OralceConnectionCacheImpl and OracleConnectionPoolDataSource. We soon found out that some of these APIs are not really pooling the connections; they are returning a new physical connection every time you ask for a connection! And most of these APIs are getting deprecated in future.

After browsing through their API set; we decided to go with the new API “oracle.jdbc.pool.OracleDataSource” for pooling! We tested this pooling in our test environment and made sure it works as expected. The connection pool configuration and the test case/results are below, we tested this with Tomcat 5.5. We changed the file context.xml for element “Resource” as below.

Adding the highlighted section to the Resource configuration section will switch a normal data source to a connection pooled data source. Notice that I have set MaxLimit as 4 for the test purpose!



<resource name="jdbc/TestPool" auth="Container" scope="Shareable" type="oracle.jdbc.pool.OracleDataSource" driverclassname="oracle.jdbc.driver.OracleDriver" factory="oracle.jdbc.pool.OracleDataSourceFactory">connectionCachingEnabled="true" connectionCacheName="TestCache" connectionCacheProperties="{MaxStatementsLimit=10, MinLimit=0, InitialLimit=0, ValidateConnection=true, ConnectionWaitTimeout=10, MaxLimit=4}" url="jdbc:oracle:thin:@199.82.16.69:1535:TESTSID" user="scott" password="tiger" />

I tested this with the below JSP code on Tomcat 5.5 server.



<%@page import="java.util.*" %>
<%@page import="java.sql.*" %>
<%@page import="javax.sql.*" %>
<%@page import="javax.naming.*" %>
<%@page import="oracle.jdbc.pool.*" %>
<HTML>
<HEAD>
<TITLE>JSP Example</TITLE>
</HEAD>
<BODY BGCOLOR="#ffffcc">
<CENTER>
<%
// Obtain our environment naming context
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
// Look up our data source
OracleDataSource ds = (OracleDataSource )envCtx.lookup("jdbc/TestPool");

ArrayList list = new ArrayList() ;
Connection conn=null;
out.println(" Opening connections <br>");
for (int i =0 ; i < 10 ; i ++ )
{ conn = ds.getConnection();
if ( conn != null ) list.add( conn );
out.println(conn+"<br>");
// don’t release here
}

// release all now
out.println(" Closing connections <br>");
while ( list.size() !=0 )
{ conn = (Connection )list.remove(0);
out.println(conn+"<br>");
conn.close();
}
%>
</CENTER>
</BODY>
</HTML>


The resulted page is given below, notice that I am trying to open 10 connections and after 4th connection, the pool returned null since I did not release the connections immediately! Also notice that I am printing the class name of the connection, and it shows “LogicalConnection” instead of “PhysicalConnection” !

Opening connections
oracle.jdbc.driver.LogicalConnection@3a0ab1
oracle.jdbc.driver.LogicalConnection@940f82
oracle.jdbc.driver.LogicalConnection@864e43
oracle.jdbc.driver.LogicalConnection@17c2891
null
null
null
null
null
null
Closing connections
oracle.jdbc.driver.LogicalConnection@3a0ab1
oracle.jdbc.driver.LogicalConnection@940f82
oracle.jdbc.driver.LogicalConnection@864e43
oracle.jdbc.driver.LogicalConnection@17c2891

Wednesday, January 16, 2008

Finding from where the java class is loaded

When programming java often times you end up in situation were whatever changes you made to the class is no reflecting when you run the code. Every time when I end up in this situation I knew that there is an old version of my class sitting some where and getting loaded in to the class path. Many of the time, you can figure out this by examining the java classpath. But most of the time the class is loaded from one of the old jar files that you don’t want to load.

To know from where the class is loaded; you can use the below code snippet

public String getClassLocation()

{

String className= this.getClass().getName();

className = className.replace('.', '/');

className = '/' + className + ".class";

java.net.URL classUrl = this.getClass().getResource(className);

String arr [] = classUrl.getFile().split ( "!") ;

return arr[0].replaceFirst("file:/","");

}

The getClassLocation function will work for any of your class and it will return the absolute path of the class file with the file name from where the class is loaded.

Thursday, January 10, 2008

Java NIO, The best thing happened to Java IO

Java 1.4 came out with NIO package that introduced a lot of new classes that java programmers were longing for a long. Few of the important features have been discussed below.

Block IO

Until now java has been doing I/O using streams, InputStream and OutputStream to be precise. The problem with stream I/O is that the I/O is carried out internally using byte by byte and hence very slow. Java uses these steams to send and receive data to external resources like files and sockets. It is also used to serialize and de-serialize java objects.

NIO is different from Stream I/O; NIO performs I/O operations in blocks. This simulates I/O closer to how operating systems optimize I/O. And hence it is fast.

Channels

The older I/O model for reading and writing used two different classes, InputStream and OutputStream, single directional classes. Often you end up creating a lot of objects for what you want to do. Various specialization of these classed were used for various type streams.

Once again java pundits though thoroughly how operating system does the I/O and came out with a better deign for I/O called a Channel. Channels are bidirectional data transfer mechanisms that allows read and write. Channels are also synchronized and provide a lot more thread safety. Like streams, there are various implementations of channels for various purposes.

Buffers

A Buffer is essentially a container object. All data that is sent to a channel must first be placed in
a buffer; likewise, any data that is read from a channel is read into a buffer. Buffers compliment channels for faster I/O, various types of buffers are,

· ByteBuffer
· CharBuffer
· ShortBuffer
· IntBuffer
· LongBuffer
· FloatBuffer
· DoubleBuffer

Buffers come with a powerful set of functions to manipulate the content of the buffer.

Memory mapped files

Memory mapped file is another great introduction to java. These are files directly mapped to the system memory. Since the content is in system memory, reads and writes as fast as accessing system memory. In real life the common usage of memory mapping is for sharing libraries, as called as shared libraries.

Asynchronous or Non-blocking I/O

Non-blocking I/O is a method for reading and writing data without blocking. Normally, when your code makes a read, the code blocks until there is data to be read. Likewise, a write will block until the data can be completely written. Also in older model, when a server opens a socket, server usually assigns a thread exclusively to serve that socket.

On the other hand, Asynchronous I/O calls non-blocking, non thread binding, it lets you do I/O from a great many inputs and outputs at the same time. As stated synchronous I/O, systems often create one thread per connection; this creates a lot of threads for serving the connections. With asynchronous I/O, you can listen for I/O events on multiple number of channels, without polling and without extra threads.

Character-set encoding and decoding

Charsets class provides encoding and decoding between charset formats like Unicode and UTF-8. This will class will make a lot of internet programmers happy

References

Java NIO package.
http://java.sun.com/j2se/1.4.2/docs/api/java/nio/package-summary.html

Book, Java NIO.
www.macdevcenter.com/catalog/javanio/