| [66] | 1 | <html><head><META http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><title>Apache Tomcat 6.0 - JNDI Datasource HOW-TO</title><meta value="Les Hughes" name="author"><meta value="leslie.hughes@rubus.com" name="email"><meta value="David Haraburda" name="author"><meta value="david-tomcat@haraburda.com" name="email"><meta value="Glenn Nielsen" name="author"><meta value="" name="email"><meta value="Yoav Shapira" name="author"><meta value="yoavs@apache.org" name="email"></head><body vlink="#525D76" alink="#525D76" link="#525D76" text="#000000" bgcolor="#ffffff"><table cellspacing="0" width="100%" border="0"><!--PAGE HEADER--><tr><td><!--PROJECT LOGO--><a href="http://tomcat.apache.org/"><img border="0" alt=" | 
|---|
|  | 2 | The Apache Tomcat Servlet/JSP Container | 
|---|
|  | 3 | " align="right" src="./../images/tomcat.gif"></a></td><td><font face="arial,helvetica,sanserif"><h1>Apache Tomcat 6.0</h1></font></td><td><!--APACHE LOGO--><a href="http://www.apache.org/"><img border="0" alt="Apache Logo" align="right" src="./../images/asf-logo.gif"></a></td></tr></table><table cellspacing="4" width="100%" border="0"><!--HEADER SEPARATOR--><tr><td colspan="2"><hr size="1" noshade></td></tr><tr><!--RIGHT SIDE MAIN BODY--><td align="left" valign="top" width="80%"><table cellspacing="4" width="100%" border="0"><tr><td valign="top" align="left"><h1>Apache Tomcat 6.0</h1><h2>JNDI Datasource HOW-TO</h2></td><td nowrap="true" valign="top" align="right"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Table of Contents"><strong>Table of Contents</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 4 | <p> | 
|---|
|  | 5 | <a href="#Introduction">Introduction</a><br> | 
|---|
|  | 6 | <a href="#Database Connection Pool (DBCP) Configurations"> | 
|---|
|  | 7 | Database Connection Pool (DBCP) Configurations</a><br> | 
|---|
|  | 8 | <a href="#Non DBCP Solutions">Non DBCP Solutions</a><br> | 
|---|
|  | 9 | <a href="#Oracle 8i with OCI client">Oracle 8i with OCI client</a><br> | 
|---|
|  | 10 | <a href="#Common Problems">Common Problems</a><br> | 
|---|
|  | 11 | </p> | 
|---|
|  | 12 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Introduction"><strong>Introduction</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 13 |  | 
|---|
|  | 14 | <p>JNDI Datasource configuration is covered extensively in the | 
|---|
|  | 15 | JNDI-Resources-HOWTO.  However, feedback from <code>tomcat-user</code> has | 
|---|
|  | 16 | shown that specifics for individual configurations can be rather tricky.</p> | 
|---|
|  | 17 |  | 
|---|
|  | 18 | <p>Here then are some example configurations that have been posted to | 
|---|
|  | 19 | tomcat-user for popular databases and some general tips for db useage.</p> | 
|---|
|  | 20 |  | 
|---|
|  | 21 | <p>You should be aware that since these notes are derived from configuration | 
|---|
|  | 22 | and/or feedback posted to <code>tomcat-user</code> YMMV :-). Please let us | 
|---|
|  | 23 | know if you have any other tested configurations that you feel may be of use | 
|---|
|  | 24 | to the wider audience, or if you feel we can improve this section in anyway.</p> | 
|---|
|  | 25 |  | 
|---|
|  | 26 | <p> | 
|---|
|  | 27 | <b>Please note that JNDI resource configuration changed somewhat between | 
|---|
|  | 28 | Tomcat 5.0.x and Tomcat 5.5.x.</b>  You will most likely need to modify older | 
|---|
|  | 29 | JNDI resource configurations to match the syntax in the example below in order | 
|---|
|  | 30 | to make them work in Tomcat 6.x.x. | 
|---|
|  | 31 | </p> | 
|---|
|  | 32 |  | 
|---|
|  | 33 | <p> | 
|---|
|  | 34 | Also, please note that JNDI DataSource configuration in general, and this | 
|---|
|  | 35 | tutorial in particular, assumes that you have read and understood the | 
|---|
|  | 36 | <a href="../config/context.html">Context</a> and | 
|---|
|  | 37 | <a href="../config/host.html">Host</a> configuration references, including | 
|---|
|  | 38 | the section about Automatic Application Deployment in the latter reference. | 
|---|
|  | 39 | </p> | 
|---|
|  | 40 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Database Connection Pool (DBCP) Configurations"><strong>Database Connection Pool (DBCP) Configurations</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 41 |  | 
|---|
|  | 42 | <p>DBCP provides support for JDBC 2.0.  On systems using a 1.4 JVM DBCP | 
|---|
|  | 43 | will support JDBC 3.0. Please let us know if you have used DBCP and its | 
|---|
|  | 44 | JDBC 3.0 features with a 1.4 JVM. | 
|---|
|  | 45 | </p> | 
|---|
|  | 46 |  | 
|---|
|  | 47 | <p>See the <a href="http://jakarta.apache.org/commons/dbcp/configuration.html"> | 
|---|
|  | 48 | DBCP documentation</a> for a complete list of configuration parameters. | 
|---|
|  | 49 | </p> | 
|---|
|  | 50 |  | 
|---|
|  | 51 | <table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#828DA6"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Installation"><strong>Installation</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 52 | <p>DBCP uses the Jakarta-Commons Database Connection Pool. It relies on | 
|---|
|  | 53 | number of Jakarta-Commons components: | 
|---|
|  | 54 | <ul> | 
|---|
|  | 55 | <li>Jakarta-Commons DBCP</li> | 
|---|
|  | 56 | <li>Jakarta-Commons Collections</li> | 
|---|
|  | 57 | <li>Jakarta-Commons Pool</li> | 
|---|
|  | 58 | </ul> | 
|---|
|  | 59 | These libraries are located in a single JAR at | 
|---|
|  | 60 | <code>$CATALINA_HOME/lib/tomcat-dbcp.jar</code>. However, | 
|---|
|  | 61 | only the classes needed for connection pooling have been included, and the | 
|---|
|  | 62 | packages have been renamed to avoid interfering with applications. | 
|---|
|  | 63 | </p> | 
|---|
|  | 64 |  | 
|---|
|  | 65 | </blockquote></td></tr></table> | 
|---|
|  | 66 |  | 
|---|
|  | 67 | <table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#828DA6"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Preventing dB connection pool leaks"><strong>Preventing dB connection pool leaks</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 68 |  | 
|---|
|  | 69 | <p> | 
|---|
|  | 70 | A database connection pool creates and manages a pool of connections | 
|---|
|  | 71 | to a database. Recycling and reusing already existing connections | 
|---|
|  | 72 | to a dB is more efficient than opening a new connection. | 
|---|
|  | 73 | </p> | 
|---|
|  | 74 |  | 
|---|
|  | 75 | <p> | 
|---|
|  | 76 | There is one problem with connection pooling.  A web application has | 
|---|
|  | 77 | to explicetely close ResultSet's, Statement's, and Connection's. | 
|---|
|  | 78 | Failure of a web application to close these resources can result in | 
|---|
|  | 79 | them never being available again for reuse, a db connection pool "leak". | 
|---|
|  | 80 | This can eventually result in your web application db connections failing | 
|---|
|  | 81 | if there are no more available connections.</p> | 
|---|
|  | 82 |  | 
|---|
|  | 83 | <p> | 
|---|
|  | 84 | There is a solution to this problem.  The Jakarta-Commons DBCP can be | 
|---|
|  | 85 | configured to track and recover these abandoned dB connections.  Not | 
|---|
|  | 86 | only can it recover them, but also generate a stack trace for the code | 
|---|
|  | 87 | which opened these resources and never closed them.</p> | 
|---|
|  | 88 |  | 
|---|
|  | 89 | <p> | 
|---|
|  | 90 | To configure a DBCP DataSource so that abandoned dB connections are | 
|---|
|  | 91 | removed and recycled add the following attribute to the | 
|---|
|  | 92 | <code>Resource</code> configuration for your DBCP DataSource: | 
|---|
|  | 93 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 94 | removeAbandoned="true" | 
|---|
|  | 95 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 96 | When available db connections run low DBCP will recover and recyle | 
|---|
|  | 97 | any abandoned dB connections it finds. The default is <code>false</code>. | 
|---|
|  | 98 | </p> | 
|---|
|  | 99 |  | 
|---|
|  | 100 | <p> | 
|---|
|  | 101 | Use the <code>removeAbandonedTimeout</code> attribute to set the number | 
|---|
|  | 102 | of seconds a dB connection has been idle before it is considered abandoned. | 
|---|
|  | 103 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 104 | removeAbandonedTimeout="60" | 
|---|
|  | 105 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 106 | The default timeout for removing abandoned connections is 300 seconds. | 
|---|
|  | 107 | </p> | 
|---|
|  | 108 |  | 
|---|
|  | 109 | <p> | 
|---|
|  | 110 | The <code>logAbandoned</code> attribute can be set to <code>true</code> | 
|---|
|  | 111 | if you want DBCP to log a stack trace of the code which abandoned the | 
|---|
|  | 112 | dB connection resources. | 
|---|
|  | 113 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 114 | logAbandoned="true" | 
|---|
|  | 115 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 116 | The default is <code>false</code>. | 
|---|
|  | 117 | </p> | 
|---|
|  | 118 |  | 
|---|
|  | 119 | </blockquote></td></tr></table> | 
|---|
|  | 120 |  | 
|---|
|  | 121 | <table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#828DA6"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="MySQL DBCP Example"><strong>MySQL DBCP Example</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 122 |  | 
|---|
|  | 123 | <h3>0. Introduction</h3> | 
|---|
|  | 124 | <p>Versions of <a href="http://www.mysql.com/products/mysql/index.html">MySQL</a> and JDBC drivers that have been reported to work: | 
|---|
|  | 125 | <ul> | 
|---|
|  | 126 | <li>MySQL 3.23.47, MySQL 3.23.47 using InnoDB,, MySQL 3.23.58,  MySQL 4.0.1alpha</li> | 
|---|
|  | 127 | <li><a href="http://www.mysql.com/products/connector-j">Connector/J</a> 3.0.11-stable (the official JDBC Driver)</li> | 
|---|
|  | 128 | <li><a href="http://mmmysql.sourceforge.net">mm.mysql</a> 2.0.14 (an old 3rd party JDBC Driver)</li> | 
|---|
|  | 129 | </ul> | 
|---|
|  | 130 | </p> | 
|---|
|  | 131 |  | 
|---|
|  | 132 | <p>Before you proceed, don't forget to copy the JDBC Driver's jar into <code>$CATALINA_HOME/lib</code>.</p> | 
|---|
|  | 133 |  | 
|---|
|  | 134 | <h3>1. MySQL configuration</h3> | 
|---|
|  | 135 | <p> | 
|---|
|  | 136 | Ensure that you follow these instructions as variations can cause problems. | 
|---|
|  | 137 | </p> | 
|---|
|  | 138 |  | 
|---|
|  | 139 | <p>Create a new test user, a new database and a single test table. | 
|---|
|  | 140 | Your MySQL user <strong>must</strong> have a password assigned. The driver | 
|---|
|  | 141 | will fail if you try to connect with an empty password. | 
|---|
|  | 142 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 143 | mysql> GRANT ALL PRIVILEGES ON *.* TO javauser@localhost | 
|---|
|  | 144 | ->   IDENTIFIED BY 'javadude' WITH GRANT OPTION; | 
|---|
|  | 145 | mysql> create database javatest; | 
|---|
|  | 146 | mysql> use javatest; | 
|---|
|  | 147 | mysql> create table testdata ( | 
|---|
|  | 148 | ->   id int not null auto_increment primary key, | 
|---|
|  | 149 | ->   foo varchar(25), | 
|---|
|  | 150 | ->   bar int); | 
|---|
|  | 151 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 152 | <blockquote> | 
|---|
|  | 153 | <strong>Note:</strong> the above user should be removed once testing is | 
|---|
|  | 154 | complete! | 
|---|
|  | 155 | </blockquote> | 
|---|
|  | 156 | </p> | 
|---|
|  | 157 |  | 
|---|
|  | 158 | <p>Next insert some test data into the testdata table. | 
|---|
|  | 159 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 160 | mysql> insert into testdata values(null, 'hello', 12345); | 
|---|
|  | 161 | Query OK, 1 row affected (0.00 sec) | 
|---|
|  | 162 |  | 
|---|
|  | 163 | mysql> select * from testdata; | 
|---|
|  | 164 | +----+-------+-------+ | 
|---|
|  | 165 | | ID | FOO   | BAR   | | 
|---|
|  | 166 | +----+-------+-------+ | 
|---|
|  | 167 | |  1 | hello | 12345 | | 
|---|
|  | 168 | +----+-------+-------+ | 
|---|
|  | 169 | 1 row in set (0.00 sec) | 
|---|
|  | 170 |  | 
|---|
|  | 171 | mysql> | 
|---|
|  | 172 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 173 | </p> | 
|---|
|  | 174 |  | 
|---|
|  | 175 | <h3>2. Context configuration</h3> | 
|---|
|  | 176 | <p>Configure the JNDI DataSource in Tomcat by adding a declaration for your | 
|---|
|  | 177 | resource to your <a href="../config/context.html">Context</a>.</p> | 
|---|
|  | 178 | <p>For example: | 
|---|
|  | 179 |  | 
|---|
|  | 180 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 181 | <Context path="/DBTest" docBase="DBTest" | 
|---|
|  | 182 | debug="5" reloadable="true" crossContext="true"> | 
|---|
|  | 183 |  | 
|---|
|  | 184 | <!-- maxActive: Maximum number of dB connections in pool. Make sure you | 
|---|
|  | 185 | configure your mysqld max_connections large enough to handle | 
|---|
|  | 186 | all of your db connections. Set to -1 for no limit. | 
|---|
|  | 187 | --> | 
|---|
|  | 188 |  | 
|---|
|  | 189 | <!-- maxIdle: Maximum number of idle dB connections to retain in pool. | 
|---|
|  | 190 | Set to -1 for no limit.  See also the DBCP documentation on this | 
|---|
|  | 191 | and the minEvictableIdleTimeMillis configuration parameter. | 
|---|
|  | 192 | --> | 
|---|
|  | 193 |  | 
|---|
|  | 194 | <!-- maxWait: Maximum time to wait for a dB connection to become available | 
|---|
|  | 195 | in ms, in this example 10 seconds. An Exception is thrown if | 
|---|
|  | 196 | this timeout is exceeded.  Set to -1 to wait indefinitely. | 
|---|
|  | 197 | --> | 
|---|
|  | 198 |  | 
|---|
|  | 199 | <!-- username and password: MySQL dB username and password for dB connections  --> | 
|---|
|  | 200 |  | 
|---|
|  | 201 | <!-- driverClassName: Class name for the old mm.mysql JDBC driver is | 
|---|
|  | 202 | org.gjt.mm.mysql.Driver - we recommend using Connector/J though. | 
|---|
|  | 203 | Class name for the official MySQL Connector/J driver is com.mysql.jdbc.Driver. | 
|---|
|  | 204 | --> | 
|---|
|  | 205 |  | 
|---|
|  | 206 | <!-- url: The JDBC connection url for connecting to your MySQL dB. | 
|---|
|  | 207 | The autoReconnect=true argument to the url makes sure that the | 
|---|
|  | 208 | mm.mysql JDBC Driver will automatically reconnect if mysqld closed the | 
|---|
|  | 209 | connection.  mysqld by default closes idle connections after 8 hours. | 
|---|
|  | 210 | --> | 
|---|
|  | 211 |  | 
|---|
|  | 212 | <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource" | 
|---|
|  | 213 | maxActive="100" maxIdle="30" maxWait="10000" | 
|---|
|  | 214 | username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver" | 
|---|
|  | 215 | url="jdbc:mysql://localhost:3306/javatest?autoReconnect=true"/> | 
|---|
|  | 216 |  | 
|---|
|  | 217 | </Context> | 
|---|
|  | 218 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 219 | </p> | 
|---|
|  | 220 |  | 
|---|
|  | 221 | <h3>3. web.xml configuration</h3> | 
|---|
|  | 222 |  | 
|---|
|  | 223 | <p>Now create a <code>WEB-INF/web.xml</code> for this test application. | 
|---|
|  | 224 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 225 | <web-app xmlns="http://java.sun.com/xml/ns/j2ee" | 
|---|
|  | 226 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | 
|---|
|  | 227 | xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee | 
|---|
|  | 228 | http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" | 
|---|
|  | 229 | version="2.4"> | 
|---|
|  | 230 | <description>MySQL Test App</description> | 
|---|
|  | 231 | <resource-ref> | 
|---|
|  | 232 | <description>DB Connection</description> | 
|---|
|  | 233 | <res-ref-name>jdbc/TestDB</res-ref-name> | 
|---|
|  | 234 | <res-type>javax.sql.DataSource</res-type> | 
|---|
|  | 235 | <res-auth>Container</res-auth> | 
|---|
|  | 236 | </resource-ref> | 
|---|
|  | 237 | </web-app> | 
|---|
|  | 238 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 239 | </p> | 
|---|
|  | 240 |  | 
|---|
|  | 241 | <h3>4. Test code</h3> | 
|---|
|  | 242 | <p>Now create a simple <code>test.jsp</code> page for use later. | 
|---|
|  | 243 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 244 | <%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %> | 
|---|
|  | 245 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> | 
|---|
|  | 246 |  | 
|---|
|  | 247 | <sql:query var="rs" dataSource="jdbc/TestDB"> | 
|---|
|  | 248 | select id, foo, bar from testdata | 
|---|
|  | 249 | </sql:query> | 
|---|
|  | 250 |  | 
|---|
|  | 251 | <html> | 
|---|
|  | 252 | <head> | 
|---|
|  | 253 | <title>DB Test</title> | 
|---|
|  | 254 | </head> | 
|---|
|  | 255 | <body> | 
|---|
|  | 256 |  | 
|---|
|  | 257 | <h2>Results</h2> | 
|---|
|  | 258 |  | 
|---|
|  | 259 | <c:forEach var="row" items="${rs.rows}"> | 
|---|
|  | 260 | Foo ${row.foo}<br/> | 
|---|
|  | 261 | Bar ${row.bar}<br/> | 
|---|
|  | 262 | </c:forEach> | 
|---|
|  | 263 |  | 
|---|
|  | 264 | </body> | 
|---|
|  | 265 | </html> | 
|---|
|  | 266 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 267 | </p> | 
|---|
|  | 268 |  | 
|---|
|  | 269 | <p>That JSP page makes use of <a href="http://java.sun.com/products/jsp/jstl">JSTL</a>'s SQL and Core taglibs. You can get it from Sun's <a href="http://java.sun.com/webservices/downloads/webservicespack.html">Java Web Services Developer Pack</a> or <a href="http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html">Jakarta Taglib Standard 1.1</a> project - just make sure you get a 1.1.x release. Once you have JSTL, copy <code>jstl.jar</code> and <code>standard.jar</code> to your web app's <code>WEB-INF/lib</code> directory. | 
|---|
|  | 270 |  | 
|---|
|  | 271 | </p> | 
|---|
|  | 272 |  | 
|---|
|  | 273 | <p>Finally deploy your web app into <code>$CATALINA_BASE/webapps</code> either | 
|---|
|  | 274 | as a warfile called <code>DBTest.war</code> or into a sub-directory called | 
|---|
|  | 275 | <code>DBTest</code></p> | 
|---|
|  | 276 | <p>Once deployed, point a browser at | 
|---|
|  | 277 | <code>http://localhost:8080/DBTest/test.jsp</code> to view the fruits of | 
|---|
|  | 278 | your hard work.</p> | 
|---|
|  | 279 |  | 
|---|
|  | 280 | </blockquote></td></tr></table> | 
|---|
|  | 281 |  | 
|---|
|  | 282 | <table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#828DA6"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Oracle 8i, 9i & 10g"><strong>Oracle 8i, 9i & 10g</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 283 | <h3>0.    Introduction</h3> | 
|---|
|  | 284 |  | 
|---|
|  | 285 | <p>Oracle requires minimal changes from the MySQL configuration except for the | 
|---|
|  | 286 | usual gotchas :-)</p> | 
|---|
|  | 287 | <p>Drivers for older Oracle versions may be distributed as *.zip files rather | 
|---|
|  | 288 | than *.jar files. Tomcat will only use <code>*.jar</code> files installed in | 
|---|
|  | 289 | <code>$CATALINA_HOME/lib</code>. Therefore <code>classes111.zip</code> | 
|---|
|  | 290 | or <code>classes12.zip</code> will need to be renamed with a <code>.jar</code> | 
|---|
|  | 291 | extension. Since jarfiles are zipfiles, there is no need to unzip and jar these | 
|---|
|  | 292 | files - a simple rename will suffice.</p> | 
|---|
|  | 293 |  | 
|---|
|  | 294 | <p>For Oracle 9i onwards you should use <code>oracle.jdbc.OracleDriver</code> | 
|---|
|  | 295 | rather than <code>oracle.jdbc.driver.OracleDriver</code> as Oracle have stated | 
|---|
|  | 296 | that <code>oracle.jdbc.driver.OracleDriver</code> is deprecated and support | 
|---|
|  | 297 | for this driver class will be discontinued in the next major release. | 
|---|
|  | 298 | </p> | 
|---|
|  | 299 |  | 
|---|
|  | 300 | <h3>1. Context configuration</h3> | 
|---|
|  | 301 | <p>In a similar manner to the mysql config above, you will need to define your | 
|---|
|  | 302 | Datasource in your <a href="../config/context.html">Context</a>. Here we define a | 
|---|
|  | 303 | Datasource called myoracle using the thin driver to connect as user scott, | 
|---|
|  | 304 | password tiger to the sid called mysid. (Note: with the thin driver this sid is | 
|---|
|  | 305 | not the same as the tnsname). The schema used will be the default schema for the | 
|---|
|  | 306 | user scott.</p> | 
|---|
|  | 307 |  | 
|---|
|  | 308 | <p>Use of the OCI driver should simply involve a changing thin to oci in the URL string. | 
|---|
|  | 309 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 310 | <Resource name="jdbc/myoracle" auth="Container" | 
|---|
|  | 311 | type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver" | 
|---|
|  | 312 | url="jdbc:oracle:thin:@127.0.0.1:1521:mysid" | 
|---|
|  | 313 | username="scott" password="tiger" maxActive="20" maxIdle="10" | 
|---|
|  | 314 | maxWait="-1"/> | 
|---|
|  | 315 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 316 | </p> | 
|---|
|  | 317 |  | 
|---|
|  | 318 | <h3>2.    web.xml configuration</h3> | 
|---|
|  | 319 | <p>You should ensure that you respect the element ordering defined by the DTD when you | 
|---|
|  | 320 | create you applications web.xml file.</p> | 
|---|
|  | 321 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 322 | <resource-ref> | 
|---|
|  | 323 | <description>Oracle Datasource example</description> | 
|---|
|  | 324 | <res-ref-name>jdbc/myoracle</res-ref-name> | 
|---|
|  | 325 | <res-type>javax.sql.DataSource</res-type> | 
|---|
|  | 326 | <res-auth>Container</res-auth> | 
|---|
|  | 327 | </resource-ref> | 
|---|
|  | 328 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 329 | <h3>3.   Code example</h3> | 
|---|
|  | 330 | <p>You can use the same example application as above (asuming you create the required DB | 
|---|
|  | 331 | instance, tables etc.) replacing the Datasource code with something like</p> | 
|---|
|  | 332 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 333 | Context initContext = new InitialContext(); | 
|---|
|  | 334 | Context envContext  = (Context)initContext.lookup("java:/comp/env"); | 
|---|
|  | 335 | DataSource ds = (DataSource)envContext.lookup("jdbc/myoracle"); | 
|---|
|  | 336 | Connection conn = ds.getConnection(); | 
|---|
|  | 337 | //etc. | 
|---|
|  | 338 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 339 | </blockquote></td></tr></table> | 
|---|
|  | 340 |  | 
|---|
|  | 341 |  | 
|---|
|  | 342 | <table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#828DA6"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="PostgreSQL"><strong>PostgreSQL</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 343 | <h3>0.    Introduction</h3> | 
|---|
|  | 344 | <p>PostgreSQL is configured in a similar manner to Oracle.</p> | 
|---|
|  | 345 |  | 
|---|
|  | 346 | <h3>1. Required files </h3> | 
|---|
|  | 347 | <p> | 
|---|
|  | 348 | Copy the Postgres JDBC jar to $CATALINA_HOME/lib. As with Oracle, the | 
|---|
|  | 349 | jars need to be in this directory in order for DBCP's Classloader to find | 
|---|
|  | 350 | them. This has to be done regardless of which configuration step you take next. | 
|---|
|  | 351 | </p> | 
|---|
|  | 352 |  | 
|---|
|  | 353 | <h3>2. Resource configuration</h3> | 
|---|
|  | 354 |  | 
|---|
|  | 355 | <p> | 
|---|
|  | 356 | You have two choices here: define a datasource that is shared across all Tomcat | 
|---|
|  | 357 | applications, or define a datasource specifically for one application. | 
|---|
|  | 358 | </p> | 
|---|
|  | 359 |  | 
|---|
|  | 360 | <h4>2a. Shared resource configuration</h4> | 
|---|
|  | 361 | <p> | 
|---|
|  | 362 | Use this option if you wish to define a datasource that is shared across | 
|---|
|  | 363 | multiple Tomcat applications, or if you just prefer defining your datasource | 
|---|
|  | 364 | in this file. | 
|---|
|  | 365 | </p> | 
|---|
|  | 366 | <p><i>This author has not had success here, although others have reported so. | 
|---|
|  | 367 | Clarification would be appreciated here.</i></p> | 
|---|
|  | 368 |  | 
|---|
|  | 369 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 370 | <Resource name="jdbc/postgres" auth="Container" | 
|---|
|  | 371 | type="javax.sql.DataSource" driverClassName="org.postgresql.Driver" | 
|---|
|  | 372 | url="jdbc:postgresql://127.0.0.1:5432/mydb" | 
|---|
|  | 373 | username="myuser" password="mypasswd" maxActive="20" maxIdle="10" maxWait="-1"/> | 
|---|
|  | 374 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 375 | <h4>2b. Application-specific resource configuration</h4> | 
|---|
|  | 376 |  | 
|---|
|  | 377 | <p> | 
|---|
|  | 378 | Use this option if you wish to define a datasource specific to your application, | 
|---|
|  | 379 | not visible to other Tomcat applications. This method is less invasive to your | 
|---|
|  | 380 | Tomcat installation. | 
|---|
|  | 381 | </p> | 
|---|
|  | 382 |  | 
|---|
|  | 383 | <p> | 
|---|
|  | 384 | Create a resource definition for your <a href="../config/context.html">Context</a>. | 
|---|
|  | 385 | The Context element should look something like the following. | 
|---|
|  | 386 | </p> | 
|---|
|  | 387 |  | 
|---|
|  | 388 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 389 | <Context path="/someApp" docBase="someApp" | 
|---|
|  | 390 | crossContext="true" reloadable="true" debug="1"> | 
|---|
|  | 391 |  | 
|---|
|  | 392 | <Resource name="jdbc/postgres" auth="Container" | 
|---|
|  | 393 | type="javax.sql.DataSource" driverClassName="org.postgresql.Driver" | 
|---|
|  | 394 | url="jdbc:postgresql://127.0.0.1:5432/mydb" | 
|---|
|  | 395 | username="myuser" password="mypasswd" maxActive="20" maxIdle="10" | 
|---|
|  | 396 | maxWait="-1"/> | 
|---|
|  | 397 | </Context> | 
|---|
|  | 398 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 399 |  | 
|---|
|  | 400 | <h3>3. web.xml configuration</h3> | 
|---|
|  | 401 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 402 | <resource-ref> | 
|---|
|  | 403 | <description>postgreSQL Datasource example</description> | 
|---|
|  | 404 | <res-ref-name>jdbc/postgres</res-ref-name> | 
|---|
|  | 405 | <res-type>javax.sql.DataSource</res-type> | 
|---|
|  | 406 | <res-auth>Container</res-auth> | 
|---|
|  | 407 | </resource-ref> | 
|---|
|  | 408 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 409 |  | 
|---|
|  | 410 | <h4>4. Accessing the datasource</h4> | 
|---|
|  | 411 | <p> | 
|---|
|  | 412 | When accessing the datasource programmatically, remember to prepend | 
|---|
|  | 413 | <code>java:/comp/env</code> to your JNDI lookup, as in the following snippet of | 
|---|
|  | 414 | code. Note also that "jdbc/postgres" can be replaced with any value you prefer, provided | 
|---|
|  | 415 | you change it in the above resource definition file as well. | 
|---|
|  | 416 | </p> | 
|---|
|  | 417 |  | 
|---|
|  | 418 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 419 | InitialContext cxt = new InitialContext(); | 
|---|
|  | 420 | if ( cxt == null ) { | 
|---|
|  | 421 | throw new Exception("Uh oh -- no context!"); | 
|---|
|  | 422 | } | 
|---|
|  | 423 |  | 
|---|
|  | 424 | DataSource ds = (DataSource) cxt.lookup( "java:/comp/env/jdbc/postgres" ); | 
|---|
|  | 425 |  | 
|---|
|  | 426 | if ( ds == null ) { | 
|---|
|  | 427 | throw new Exception("Data source not found!"); | 
|---|
|  | 428 | } | 
|---|
|  | 429 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 430 |  | 
|---|
|  | 431 | </blockquote></td></tr></table> | 
|---|
|  | 432 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Non-DBCP Solutions"><strong>Non-DBCP Solutions</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 433 | <p> | 
|---|
|  | 434 | These solutions either utilise a single connection to the database (not recommended for anything other | 
|---|
|  | 435 | than testing!) or some other pooling technology. | 
|---|
|  | 436 | </p> | 
|---|
|  | 437 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Oracle 8i with OCI client"><strong>Oracle 8i with OCI client</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 438 | <table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#828DA6"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Introduction"><strong>Introduction</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 439 | <p>Whilst not strictly addressing the creation of a JNDI DataSource using the OCI client, these notes can be combined with the | 
|---|
|  | 440 | Oracle and DBCP solution above.</p> | 
|---|
|  | 441 | <p> | 
|---|
|  | 442 | In order to use OCI driver, you should have an Oracle client installed. You should have installed | 
|---|
|  | 443 | Oracle8i(8.1.7) client from cd,  and download the suitable JDBC/OCI | 
|---|
|  | 444 | driver(Oracle8i 8.1.7.1 JDBC/OCI Driver) from <a href="http://otn.oracle.com/">otn.oracle.com</a>. | 
|---|
|  | 445 | </p> | 
|---|
|  | 446 | <p> | 
|---|
|  | 447 | After renaming <code>classes12.zip</code> file to <code>classes12.jar</code> | 
|---|
|  | 448 | for Tomcat, copy it into <code>$CATALINA_HOME/lib</code>. | 
|---|
|  | 449 | You may also have to remove the <code>javax.sql.*</code> classes | 
|---|
|  | 450 | from this file depending upon the version of Tomcat and JDK you are using. | 
|---|
|  | 451 | </p> | 
|---|
|  | 452 | </blockquote></td></tr></table> | 
|---|
|  | 453 |  | 
|---|
|  | 454 | <table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#828DA6"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Putting it all together"><strong>Putting it all together</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 455 | <p> | 
|---|
|  | 456 | Ensure that you have the <code>ocijdbc8.dll</code> or <code>.so</code> in your <code>$PATH</code> or <code>LD_LIBRARY_PATH</code> | 
|---|
|  | 457 | (possibly in <code>$ORAHOME\bin</code>) and also confirm that the native library can be loaded by a simple test program | 
|---|
|  | 458 | using <code>System.loadLibrary("ocijdbc8");</code> | 
|---|
|  | 459 | </p> | 
|---|
|  | 460 | <p> | 
|---|
|  | 461 | You should next create a simple test servlet or jsp that has these | 
|---|
|  | 462 | <strong>critical lines</strong>: | 
|---|
|  | 463 | </p> | 
|---|
|  | 464 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> | 
|---|
|  | 465 | DriverManager.registerDriver(new | 
|---|
|  | 466 | oracle.jdbc.driver.OracleDriver()); | 
|---|
|  | 467 | conn = | 
|---|
|  | 468 | DriverManager.getConnection("jdbc:oracle:oci8:@database","username","password"); | 
|---|
|  | 469 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> | 
|---|
|  | 470 | <p> | 
|---|
|  | 471 | where database is of the form <code>host:port:SID</code> Now if you try to access the URL of your | 
|---|
|  | 472 | test servlet/jsp and what you get is a | 
|---|
|  | 473 | <code>ServletException</code> with a root cause of <code>java.lang.UnsatisfiedLinkError:get_env_handle</code>. | 
|---|
|  | 474 | </p> | 
|---|
|  | 475 | <p> | 
|---|
|  | 476 | First, the <code>UnsatisfiedLinkError</code> indicates that you have | 
|---|
|  | 477 | <ul> | 
|---|
|  | 478 | <li>a mismatch between your JDBC classes file and | 
|---|
|  | 479 | your Oracle client version. The giveaway here is the message stating that a needed library file cannot be | 
|---|
|  | 480 | found. For example, you may be using a classes12.zip file from Oracle Version 8.1.6 with a Version 8.1.5 | 
|---|
|  | 481 | Oracle client. The classeXXXs.zip file and Oracle client software versions must match. | 
|---|
|  | 482 | </li> | 
|---|
|  | 483 | <li>A <code>$PATH</code>, <code>LD_LIBRARY_PATH</code> problem.</li> | 
|---|
|  | 484 | <li>It has been reported that ignoring the driver you have downloded from otn and using | 
|---|
|  | 485 | the classes12.zip file from the directory <code>$ORAHOME\jdbc\lib</code> will also work. | 
|---|
|  | 486 | </li> | 
|---|
|  | 487 | </ul> | 
|---|
|  | 488 | </p> | 
|---|
|  | 489 | <p> | 
|---|
|  | 490 | Next you may experience the error <code>ORA-06401 NETCMN: invalid driver designator</code> | 
|---|
|  | 491 | </p> | 
|---|
|  | 492 | <p> | 
|---|
|  | 493 | The Oracle documentation says : "Cause: The login (connect) string contains an invalid | 
|---|
|  | 494 | driver designator. Action: Correct the string and re-submit." | 
|---|
|  | 495 |  | 
|---|
|  | 496 | Change the database connect string (of the form <code>host:port:SID</code>) with this one: | 
|---|
|  | 497 | <code>(description=(address=(host=myhost)(protocol=tcp)(port=1521))(connect_data=(sid=orcl)))</code> | 
|---|
|  | 498 | </p> | 
|---|
|  | 499 | <p> | 
|---|
|  | 500 | <i>Ed. Hmm, I don't think this is really needed if you sort out your TNSNames - but I'm not an Oracle DBA :-)</i> | 
|---|
|  | 501 | </p> | 
|---|
|  | 502 | </blockquote></td></tr></table> | 
|---|
|  | 503 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Common Problems"><strong>Common Problems</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 504 | <p>Here are some common problems encountered with a web application which | 
|---|
|  | 505 | uses a database and tips for how to solve them.</p> | 
|---|
|  | 506 |  | 
|---|
|  | 507 | <table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#828DA6"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Intermittent dB Connection Failures"><strong>Intermittent dB Connection Failures</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 508 | <p> | 
|---|
|  | 509 | Tomcat runs within a JVM.  The JVM periodically performs garbage collection | 
|---|
|  | 510 | (GC) to remove java objects which are no longer being used.  When the JVM | 
|---|
|  | 511 | performs GC execution of code within Tomcat freezes. If the maximum time | 
|---|
|  | 512 | configured for establishment of a dB connection is less than the amount | 
|---|
|  | 513 | of time garbage collection took you can get a db conneciton failure. | 
|---|
|  | 514 | </p> | 
|---|
|  | 515 |  | 
|---|
|  | 516 | <p>To collect data on how long garbage collection is taking add the | 
|---|
|  | 517 | <code>-verbose:gc</code> argument to your <code>CATALINA_OPTS</code> | 
|---|
|  | 518 | environment variable when starting Tomcat.  When verbose gc is enabled | 
|---|
|  | 519 | your <code>$CATALINA_BASE/logs/catalina.out</code> log file will include | 
|---|
|  | 520 | data for every garbage collection including how long it took.</p> | 
|---|
|  | 521 |  | 
|---|
|  | 522 | <p>When your JVM is tuned correctly 99% of the time a GC will take less | 
|---|
|  | 523 | than one second.  The remainder will only take a few seconds.  Rarely, | 
|---|
|  | 524 | if ever should a GC take more than 10 seconds.</p> | 
|---|
|  | 525 |  | 
|---|
|  | 526 | <p>Make sure that the db connection timeout is set to 10-15 seconds. | 
|---|
|  | 527 | For the DBCP you set this using the parameter <code>maxWait</code>.</p> | 
|---|
|  | 528 |  | 
|---|
|  | 529 | </blockquote></td></tr></table> | 
|---|
|  | 530 |  | 
|---|
|  | 531 | <table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#828DA6"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Random Connection Closed Exceptions"><strong>Random Connection Closed Exceptions</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 532 | <p> | 
|---|
|  | 533 | These can occur when one request gets a db connection from the connection | 
|---|
|  | 534 | pool and closes it twice.  When using a connection pool, closing the | 
|---|
|  | 535 | connection just returns it to the pool for reuse by another request, | 
|---|
|  | 536 | it doesn't close the connection.  And Tomcat uses multiple threads to | 
|---|
|  | 537 | handle concurrent requests. Here is an example of the sequence | 
|---|
|  | 538 | of events which could cause this error in Tomcat: | 
|---|
|  | 539 | <pre> | 
|---|
|  | 540 | Request 1 running in Thread 1 gets a db connection. | 
|---|
|  | 541 |  | 
|---|
|  | 542 | Request 1 closes the db connection. | 
|---|
|  | 543 |  | 
|---|
|  | 544 | The JVM switches the running thread to Thread 2 | 
|---|
|  | 545 |  | 
|---|
|  | 546 | Request 2 running in Thread 2 gets a db connection | 
|---|
|  | 547 | (the same db connection just closed by Request 1). | 
|---|
|  | 548 |  | 
|---|
|  | 549 | The JVM switches the running thread back to Thread 1 | 
|---|
|  | 550 |  | 
|---|
|  | 551 | Request 1 closes the db connection a second time in a finally block. | 
|---|
|  | 552 |  | 
|---|
|  | 553 | The JVM switches the running thread back to Thread 2 | 
|---|
|  | 554 |  | 
|---|
|  | 555 | Request 2 Thread 2 tries to use the db connection but fails | 
|---|
|  | 556 | because Request 1 closed it. | 
|---|
|  | 557 | </pre> | 
|---|
|  | 558 | Here is an example of properly written code to use a db connection | 
|---|
|  | 559 | obtained from a connection pool: | 
|---|
|  | 560 | <pre> | 
|---|
|  | 561 | Connection conn = null; | 
|---|
|  | 562 | Statement stmt = null;  // Or PreparedStatement if needed | 
|---|
|  | 563 | ResultSet rs = null; | 
|---|
|  | 564 | try { | 
|---|
|  | 565 | conn = ... get connection from connection pool ... | 
|---|
|  | 566 | stmt = conn.createStatement("select ..."); | 
|---|
|  | 567 | rs = stmt.executeQuery(); | 
|---|
|  | 568 | ... iterate through the result set ... | 
|---|
|  | 569 | rs.close(); | 
|---|
|  | 570 | rs = null; | 
|---|
|  | 571 | stmt.close(); | 
|---|
|  | 572 | stmt = null; | 
|---|
|  | 573 | conn.close(); // Return to connection pool | 
|---|
|  | 574 | conn = null;  // Make sure we don't close it twice | 
|---|
|  | 575 | } catch (SQLException e) { | 
|---|
|  | 576 | ... deal with errors ... | 
|---|
|  | 577 | } finally { | 
|---|
|  | 578 | // Always make sure result sets and statements are closed, | 
|---|
|  | 579 | // and the connection is returned to the pool | 
|---|
|  | 580 | if (rs != null) { | 
|---|
|  | 581 | try { rs.close(); } catch (SQLException e) { ; } | 
|---|
|  | 582 | rs = null; | 
|---|
|  | 583 | } | 
|---|
|  | 584 | if (stmt != null) { | 
|---|
|  | 585 | try { stmt.close(); } catch (SQLException e) { ; } | 
|---|
|  | 586 | stmt = null; | 
|---|
|  | 587 | } | 
|---|
|  | 588 | if (conn != null) { | 
|---|
|  | 589 | try { conn.close(); } catch (SQLException e) { ; } | 
|---|
|  | 590 | conn = null; | 
|---|
|  | 591 | } | 
|---|
|  | 592 | } | 
|---|
|  | 593 | </pre> | 
|---|
|  | 594 | </p> | 
|---|
|  | 595 |  | 
|---|
|  | 596 | </blockquote></td></tr></table> | 
|---|
|  | 597 |  | 
|---|
|  | 598 | <table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#828DA6"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Context versus GlobalNamingResources"><strong>Context versus GlobalNamingResources</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 599 | <p> | 
|---|
|  | 600 | Please note that although the above instructions place the JNDI declarations in a Context | 
|---|
|  | 601 | element, it is possible and sometimes desirable to place these declarations in the | 
|---|
|  | 602 | <a href="../config/globalresources.html">GlobalNamingResources</a> section of the server | 
|---|
|  | 603 | configuration file.  A resource placed in the GlobalNamingResources section will be shared | 
|---|
|  | 604 | among the Contexts of the server. | 
|---|
|  | 605 | </p> | 
|---|
|  | 606 | </blockquote></td></tr></table> | 
|---|
|  | 607 |  | 
|---|
|  | 608 | <table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#828DA6"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="JNDI Resource Naming and Realm Interaction"><strong>JNDI Resource Naming and Realm Interaction</strong></a></font></td></tr><tr><td><blockquote> | 
|---|
|  | 609 | <p> | 
|---|
|  | 610 | In order to get Realms to work, the realm must refer to the datasource as | 
|---|
|  | 611 | defined in the <GlobalNamingResources> or <Context> section, not a datasource as renamed | 
|---|
|  | 612 | using <ResourceLink>. | 
|---|
|  | 613 | </p> | 
|---|
|  | 614 | </blockquote></td></tr></table> | 
|---|
|  | 615 |  | 
|---|
|  | 616 | </blockquote></td></tr></table></td></tr><!--FOOTER SEPARATOR--><tr><td colspan="2"><hr size="1" noshade></td></tr><!--PAGE FOOTER--><tr><td colspan="2"><div align="center"><font size="-1" color="#525D76"><em> | 
|---|
|  | 617 | Copyright © 1999-2008, Apache Software Foundation | 
|---|
|  | 618 | </em></font></div></td></tr></table></body></html> | 
|---|