How to Setup JSTL & JNDI
for MySQL 4.x JDBC Connection Pooling
with Tomcat 5.0 and 5.5

by Gregg Lagnese, MicroDeveloper, Inc.
March 8, 2005
 
Preface
This document outlines the step necessary to setup JSTL (JSP Tag Libraries) & JNDI resources on Tomcat for accessing MySQL databases, versions 4.0 through 4.1.  This paper uses JSTL merely for convienience in the examples, however it proved to be the trickier aspect in setup. If you are running a relatively current JDK you should be fine. This setup was tested under OS X and Windows using JDK 1.4.2_05 and Tomcat 5.0.28 and Tomcat 5.5.7.
 
Nomenclature:
<name> = where you substitute the necessary value
[name] = an optional element or parameter


Note
: All examples are given in Unix path notation, use Windows notation where applicable.
 

Section Index

Configuration

Testing the changes
Troubleshooting
Making a User Dependent Connection
 

Configuration

 
Pre-requisite setup:
To begin with, you will need the following Jars (not zips) in your $CATALINA_BASE/<5.x>/common/lib directory.

Note: You only need naming-common.jar with 5.0 implementations, do not include it with 5.5 (or Tomcat will not start) because it is already bundled in the other 5.5 version of the factory Jar.

/usr/local/tomcat/5.5.7/common/lib

commons-collections-3.1.jar
commons-dbcp-1.2.1.jar
commons-el.jar
commons-pool-1.2.jar jasper-compiler-jdt.jar
jasper-compiler.jar
jasper-runtime.jar
jsp-api.jar jstl.jar mysql-connector-java-3.1.8-bin.jar naming-java.jar naming-factory.jar naming-factory-dbcp.jar naming-resources.jar
servlet-api.jar

For 5.0.x add this Jar:
naming-common.jar

If you don't have some of these, you can get the entire 5.5.7 bundle here (less the naming-common.jar file).
Unix/Linux/Mac OS X
Windows (Zip)

 
The JSTL Jar file can be placed in your <CONTEXT_ROOT>/WEB-INF/lib directory or globally deployed with the files above as shown.
 
Database Setup:
Make sure you have MySQL setup already and that you can connect to it remotely. This paper assumes you will be using the "test" database with a user called "scott". Substitute your database and usernames accordingly. I created a simple test table called messages with using the following quick steps:
glagnese:/ $ mysql -h mysql.microdeveloper.com -u scott -p

Enter password: 

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 31 to server version: 4.1.9-nt-max
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> connect test
     Connection id: 32
     Current database: test

mysql> create table messages (text_message varchar(50));
Query OK, 0 rows affected (0.31 sec)
mysql> insert into messages values ('hello world');
Query OK, 1 row affected (0.05 sec)
mysql> insert into messages values ('Hello USA');
Query OK, 1 row affected (0.01 sec)
mysql> insert into messages values ('Hello Next Door');
     Query OK, 1 row affected (0.01 sec)
mysql> insert into messages values ('Hello Me');
     Query OK, 1 row affected (0.00 sec)
mysql> commit;
     Query OK, 0 rows affected (0.00 sec)

mysql> select * from messages;
+-----------------+
| text_message |
+-----------------+
| hello world |
| Hello USA |
| Hello Next Door |
| Hello Me |
+-----------------+
4 rows in set (0.00 sec)
mysql> exit
Bye
 
Steps to Implement:
1) Modify the server.xml file
In <CATALINA_HOME>/conf/server.xml between <Host> and </Host> add the following
<Context path="/dvdlib" docBase="dvdlib"       debug="5" reloadable="true" crossContext="true">
       
    <Resource name="jdbc/<alias>" 
       auth="Container"
       type="javax.sql.DataSource"
       maxActive="100" 
       maxIdle="30" 
       maxWait="10000"
       username="dvdlib"
       driverClassName="com.mysql.jdbc.Driver"
       url="jdbc:mysql://<server>:<port>/<database>?autoReconnect=true"/>
         
 </Context>
Example
<Engine defaultHost="localhost" name="Catalina">
   <Realm className="org.apache.catalina.realm.UserDatabaseRealm"/>
   <Host
       appBase="webapps"
       name="localhost">
   
      <Context path="/mydb" docBase="/mydb" debug="5" reloadable="true" crossContext="true">
         <Resource name="jdbc/test" 
             auth="Container"
             type="javax.sql.DataSource"
             maxActive="100" 
             maxIdle="30" 
             maxWait="10000"
             username="dvdlib"
             driverClassName="com.mysql.jdbc.Driver"
             url="jdbc:mysql://mysql.microdeveloper.com:3306/test?autoReconnect=true"/>
      </Context>
 
   </Host>
</Engine>
 
 
2) Modify the Context's web.xml file
In the <CONTEXT_HOME>/WEB-INF/web.xml after the <?xml version="1.0" encoding="ISO-8859-1"?> tag add (or change) the following. This must be version 2.4 (not 2.3) or the JSTL will not work.
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
 
Then add a resource reference to the new datasource inside the web-app container in the same file.
   <description>Your Description</description>
   <resource-ref>
     <description>Connection Description</description>
     <res-ref-name>jdbc/<alias></res-ref-name>
     <res-type>javax.sql.DataSource</res-type>
     <res-auth>Container</res-auth>
   </resource-ref>
 
Example
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
   <description>This is a simple JSTL-JNDI test application</description>
   <resource-ref>
     <description>MySQL Database Connection</description>
     <res-ref-name>jdbc/test</res-ref-name>
     <res-type>javax.sql.DataSource</res-type>
     <res-auth>Container</res-auth>
   </resource-ref>
</web-app>
 
3) Restart Tomcat
 
 

Testing the Changes

4) Test that JSTL is working first.
Create a simple JSP page that ensures JSTL is working before proceeding. If this is not working, get it working first. Make sure the JSTL jar is deployed and make sure the web.xml file is setup for 2.4. That last element tripped me up several times.
<%@ page contentType="text/html" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>JSP is Easy</title>
</head>
<body bgcolor="white"> <h1>JSP is as easy as ...</h1> <%-- Calculate the sum of 1 + 2 + 3 dynamically --%> 1 + 2 + 3 = <c:out value="${1 + 2 + 3}" /> </body> </html>
 
Result

JSP is as easy as ...

1 + 2 + 3 = 6
 
5) Create another JSP to test the JNDI connection with.
 
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<sql:query var="rs" dataSource="jdbc/mydb">
  select text_message from messages
</sql:query>

<html>
  <head>
    <title>DB Test</title>
  </head>
  <body>
    <h2>Results</h2>
    <c:forEach var="i" items="${rs.rows}">
      Text Message: <c:out value="${i.text_message}"/><br>
    </c:forEach>
  </body>
</html>
 
 

Results

Text Message: hello world
Text Message: Hello USA
Text Message: Hello Next Door
Text Message: Hello Me
 
 

Troubleshooting

 
6) Check the database first
Verify database connectivity
a) Ping the server
b) Connect using the username and password in step 1
c) Verify the server and port
 
7) Driver error messages

Driver errors usually look like (Cannot create JDBC driver of class '' for connect URL 'null'):
Place the mysql-connector-java-3.1.6-bin.jar file in the <CATALINA_HOME>\common\lib directory
Do NOT place the JAR in your <CONTEXT>/WEB-INF/lib directory (this can cause problems)
If used with an IDE that auto-deploys, exclude the JAR from the deployment

Error messages that 'jdbc' is an unknown context:
Verify that the alias and the database names are correct and that you are using the alias in your calls. Check your alias and database configurations in the web.xml and server.xml files.

Make sure JSTL is working:
Verify that JSTL is working properly by using the test page given above. Make sure the web.xml uses the 2.4 syntax.

 
 
This method has been tested on MySQL 4.1.9 and Tomcat 5.0.24 and 5.5.7. It was tested using Netbeans 3.6, Netbeans 4.0, and IntelliJ 4.5.
 
Revision History
06.15.06.01     glagnese     Changed the instructions for context specific installation rather than global installation.
03.08.05.01     glagnese     Created.

Gregg Lagnese is an senior executive and developer for MicroDeveloper, Inc. and has been developing software for Oracle databases for more than 14 years.