0% found this document useful (0 votes)
55 views21 pages

Apache Tomcat 6

The document discusses how to set up Tomcat on different platforms including Windows and Unix. It also covers installing Tomcat as a service on Windows and running it as a daemon on Unix systems.

Uploaded by

stefy012raz
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
55 views21 pages

Apache Tomcat 6

The document discusses how to set up Tomcat on different platforms including Windows and Unix. It also covers installing Tomcat as a service on Windows and running it as a daemon on Unix systems.

Uploaded by

stefy012raz
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 21

Tomcat Setup

Table of Contents
 Introduction
 Windows
 Unix daemon

Introduction
There are several ways to set up Tomcat for running on different platforms. The main
documentation for this is a file called RUNNING.txt. We encourage you to refer to that file
if the information below does not answer some of your questions.

Windows
Installing Tomcat on Windows can be done easily using the Windows installer. Its interface
and functionality is similar to other wizard based installers, with only a few items of interest.

 Installation as a service: Tomcat will be installed as a Windows service no


matter what setting is selected. Using the checkbox on the component page
sets the service as "auto" startup, so that Tomcat is automatically started when
Windows starts. For optimal security, the service should be run as a separate
user, with reduced permissions (see the Windows Services administration tool
and its documentation).
 Java location: The installer will provide a default JRE to use to run the
service. The installer uses the registry to determine the base path of a Java 5
or later JRE, including the JRE installed as part of the full JDK. When
running on a 64-bit operating system, the installer will first look for a 64-bit
JRE and only look for a 32-bit JRE if a 64-bit JRE is not found. It is not
mandatory to use the default JRE detected by the installer. Any installed Java
5 or later JRE (32-bit or 64-bit) may be used.
 Tray icon: When Tomcat is run as a service, there will not be any tray icon
present when Tomcat is running. Note that when choosing to run Tomcat at
the end of installation, the tray icon will be used even if Tomcat was installed
as a service.
 Refer to the Windows Service HOW-TO for information on how to manage
Tomcat as a Windows service.

The installer will create shortcuts allowing starting and configuring Tomcat. It is important
to note that the Tomcat administration web application can only be used when Tomcat is
running.
Unix daemon
Tomcat can be run as a daemon using the jsvc tool from the commons-daemon project.
Source tarballs for jsvc are included with the Tomcat binaries, and need to be compiled.
Building jsvc requires a C ANSI compiler (such as GCC), GNU Autoconf, and a JDK.

Before running the script, the JAVA_HOME environment variable should be set to the base path
of the JDK. Alternately, when calling the ./configure script, the path of the JDK may be
specified using the --with-java parameter, such as ./configure
--with-java=/usr/java.

Using the following commands should result in a compiled jsvc binary, located in
the $CATALINA_HOME/bin folder. This assumes that GNU TAR is used, and
that CATALINA_HOME is an environment variable pointing to the base path of the Tomcat
installation.

Please note that you should use the GNU make (gmake) instead of the native BSD make on
FreeBSD systems.

cd $CATALINA_HOME/bin
tar xvfz commons-daemon-native.tar.gz
cd commons-daemon-1.0.x-native-src/unix
./configure
make
cp jsvc ../..
cd ../..

Tomcat can then be run as a daemon using the following commands.

CATALINA_BASE=$CATALINA_HOME
cd $CATALINA_HOME
./bin/jsvc \
-classpath $CATALINA_HOME/bin/bootstrap.jar \
-outfile $CATALINA_BASE/logs/catalina.out \
-errfile $CATALINA_BASE/logs/catalina.err \
-Dcatalina.home=$CATALINA_HOME \
-Dcatalina.base=$CATALINA_BASE \
-
Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \

-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties \
org.apache.catalina.startup.Bootstrap

jsvc has other useful parameters, such as -user which causes it to switch to another user
after the daemon initialization is complete. This allows, for example, running Tomcat as a
non privileged user while still being able to use privileged ports. jsvc --help will return
the full jsvc usage information. In particular, the -debug option is useful to debug issues
running jsvc.

The file $CATALINA_HOME/bin/daemon.sh can be used as a template for starting Tomcat


automatically at boot time from /etc/init.d with jsvc.

Note that the Commons-Daemon JAR file must be on your runtime classpath to run Tomcat
in this manner. The Commons-Daemon JAR file is in the Class-Path entry of the
bootstrap.jar manifest, but if you get a ClassNotFoundException or a
NoClassDefFoundError for a Commons-Daemon class, add the Commons-Daemon JAR to
the -cp argument when launching jsvc.

Apache Tomcat 6.0


JNDI Resources HOW-TO
Table of Contents
 Introduction
 web.xml configuration
 context.xml configuration
 Global configuration
 Using resources
 Tomcat Standard Resource Factories
1. Generic JavaBean Resources
2. UserDatabase Resources
3. JavaMail Sessions
4. JDBC Data Sources
 Adding Custom Resource Factories

Introduction
Tomcat 6 provides a JNDI InitialContext implementation instance for each web application
running under it, in a manner that is compatible with those provided by a Java2 Enterprise
Edition application server. The J2EE standard provides a standard set of elements in
the /WEB-INF/web.xml file to reference/define resources.

See the following Specifications for more information about programming APIs for JNDI,
and for the features supported by Java2 Enterprise Edition (J2EE) servers, which Tomcat
emulates for the services that it provides:

 Java Naming and Directory Interface (included in JDK 1.4 onwards)


 J2EE Platform Specification (in particular, see Chapter 5 on Naming)

web.xml configuration
The following elements may be used in the web application deployment descriptor (/WEB-
INF/web.xml) of your web application to define resources:

 <env-entry> - Environment entry, a single-value parameter that can be used


to configure how the application will operate.
 <resource-ref> - Resource reference, which is typically to an object factory
for resources such as a JDBC DataSource, a JavaMail Session, or custom
object factories configured into Tomcat 6.
 <resource-env-ref> - Resource environment reference, a new variation
of resource-ref added in Servlet 2.4 that is simpler to configure for
resources that do not require authentication information.

Providing that Tomcat is able to identify an appropriate resource factory to use to create the
resource and that no further configuration information is required, Tomcat will use the
information in /WEB-INF/web.xml to create the resource.
context.xml configuration
If Tomcat is unable to identify the appropriate resource factory and/or additional
configuration information is required, additional Tomcat specific configuration must be
specified before Tomcat can create the resource. Tomcat specific resource configuration is
entered in the <Context> elements that can be specified in
either $CATALINA_BASE/conf/server.xml or, preferably, the per-web-application context
XML file (META-INF/context.xml).

Tomcat specific resource configuration is performed using the following elements in


the <Context> element:

 <Environment> - Configure names and values for scalar environment entries


that will be exposed to the web application through the
JNDI InitialContext (equivalent to the inclusion of an <env-
entry> element in the web application deployment descriptor).
 <Resource> - Configure the name and data type of a resource made available
to the application (equivalent to the inclusion of a <resource-ref> element
in the web application deployment descriptor).
 <ResourceLink> - Add a link to a resource defined in the global JNDI
context. Use resource links to give a web application access to a resource
defined in the <GlobalNamingResources> child element of
the <Server> element.
 <Transaction> - Add a resource factory for instantiating the UserTransaction
object instance that is available at java:comp/UserTransaction.

Any number of these elements may be nested inside a <Context> element and will be
associated only with that particular web application.

If a resource has been defined in a <Context> element it is not necessary for that resource to
be defined in /WEB-INF/web.xml. However, it is recommended to keep the entry in /WEB-
INF/web.xml to document the resource requirements for the web application.

Where the same resource name has been defined for a <env-entry> element included in the
web application deployment descriptor (/WEB-INF/web.xml) and in
an <Environment> element as part of the <Context> element for the web application, the
values in the deployment descriptor will take precedence only if allowed by the
corresponding <Environment> element (by setting the override attribute to "true").
Global configuration
Tomcat 6 maintains a separate namespace of global resources for the entire server. These are
configured in the <GlobalNamingResources> element
of $CATALINA_BASE/conf/server.xml. You may expose these resources to web
applications by using a <ResourceLink> to include it in the per-web-application context.

If a resource has been defined using a <ResourceLink>, it is not necessary for that resource
to be defined in /WEB-INF/web.xml. However, it is recommended to keep the entry in /WEB-
INF/web.xml to document the resource requirements for the web application.
Using resources
The InitialContext is configured as a web application is initially deployed, and is made
available to web application components (for read-only access). All configured entries and
resources are placed in the java:comp/env portion of the JNDI namespace, so a typical
access to a resource - in this case, to a JDBC DataSource - would look something like this:

// Obtain our environment naming context


Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");

// Look up our data source


DataSource ds = (DataSource)
envCtx.lookup("jdbc/EmployeeDB");

// Allocate and use a connection from the pool


Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();

Tomcat Standard Resource Factories


Tomcat 6 includes a series of standard resource factories that can provide services to your
web applications, but give you configuration flexibility (via the <Context> element) without
modifying the web application or the deployment descriptor. Each subsection below details
the configuration and usage of the standard resource factories.

See Adding Custom Resource Factories for information about how to create, install,
configure, and use your own custom resource factory classes with Tomcat 6.

NOTE - Of the standard resource factories, only the "JDBC Data Source" and "User
Transaction" factories are mandated to be available on other platforms, and then they are
required only if the platform implements the Java2 Enterprise Edition (J2EE) specs. All
other standard resource factories, plus custom resource factories that you write yourself, are
specific to Tomcat and cannot be assumed to be available on other containers.

Generic JavaBean Resources


0. Introduction

This resource factory can be used to create objects of any Java class that conforms to
standard JavaBeans naming conventions (i.e. it has a zero-arguments constructor, and has
property setters that conform to the setFoo() naming pattern. The resource factory will
create a new instance of the appropriate bean class every time a lookup() for this entry is
made.

The steps required to use this facility are described below.

1. Create Your JavaBean Class

Create the JavaBean class which will be instantiated each time that the resource factory is
looked up. For this example, assume you create a class com.mycompany.MyBean, which
looks like this:

package com.mycompany;

public class MyBean {

private String foo = "Default Foo";

public String getFoo() {


return (this.foo);
}

public void setFoo(String foo) {


this.foo = foo;
}

private int bar = 0;

public int getBar() {


return (this.bar);
}

public void setBar(int bar) {


this.bar = bar;
}

2. Declare Your Resource Requirements

Next, modify your web application deployment descriptor (/WEB-INF/web.xml) to declare


the JNDI name under which you will request new instances of this bean. The simplest
approach is to use a <resource-env-ref> element, like this:

<resource-env-ref>
<description>
Object factory for MyBean instances.
</description>
<resource-env-ref-name>
bean/MyBeanFactory
</resource-env-ref-name>
<resource-env-ref-type>
com.mycompany.MyBean
</resource-env-ref-type>
</resource-env-ref>

WARNING - Be sure you respect the element ordering that is required by the DTD for web
application deployment descriptors! See the Servlet Specification for details.

3. Code Your Application's Use Of This Resource

A typical use of this resource environment reference might look like this:

Context initCtx = new InitialContext();


Context envCtx = (Context) initCtx.lookup("java:comp/env");
MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");

writer.println("foo = " + bean.getFoo() + ", bar = " +


bean.getBar());

4. Configure Tomcat's Resource Factory

To configure Tomcat's resource factory, add an element like this to the <Context> element
for this web application.

<Context ...>
...
<Resource name="bean/MyBeanFactory" auth="Container"
type="com.mycompany.MyBean"
factory="org.apache.naming.factory.BeanFactory"
bar="23"/>
...
</Context>

Note that the resource name (here, bean/MyBeanFactory must match the value specified in
the web application deployment descriptor. We are also initializing the value of
the bar property, which will cause setBar(23) to be called before the new bean is returned.
Because we are not initializing the foo property (although we could have), the bean will
contain whatever default value is set up by its constructor.
UserDatabase Resources
0. Introduction

UserDatabase resources are typically configured as global resources for use by a


UserDatabase realm. Tomcat includes a UserDatabaseFactoory that creates UserDatabase
resources backed by an XML file - usually tomcat-users.xml
The steps required to set up a global UserDatabase resource are described below.

1. Create/edit the XML file

The XMl file is typically located at $CATALINA_BASE/conf/tomcat-users.xml however,


you are free to locate the file anywhere on the file system. It is recommended that the XML
files are placed in $CATALINA_BASE/conf. A typical XML would look like:

<?xml version='1.0' encoding='utf-8'?>


<tomcat-users>
<role rolename="tomcat"/>
<role rolename="role1"/>
<user username="tomcat" password="tomcat" roles="tomcat"/>
<user username="both" password="tomcat" roles="tomcat,role1"/>
<user username="role1" password="tomcat" roles="role1"/>
</tomcat-users>

2. Declare Your Resource

Next, modify $CATALINA_BASE/conf/server.xml to create the UserDatabase resource


based on your XMl file. It should look something like this:

<Resource name="UserDatabase"
auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml"
readonly="false" />

The pathname attribute can be absolute or relative. If relative, it is relative


to $CATALINA_BASE.

The readonly attribute is optional and defaults to true if not supplied. If the XML is
writeable then it will be written to when Tomcat starts. WARNING: When the file is
written it will inherit the default file permissions for the user Tomcat is running as. Ensure
that these are appropriate to maintain the security of your installation.

3. Configure the Realm

Configure a UserDatabase Realm to use this resource as described in the Realm


configuration documentation.
JavaMail Sessions
0. Introduction

In many web applications, sending electronic mail messages is a required part of the
system's functionality. The Java Mail API makes this process relatively straightforward, but
requires many configuration details that the client application must be aware of (including
the name of the SMTP host to be used for message sending).

Tomcat 6 includes a standard resource factory that will create javax.mail.Session session
instances for you, already configured to connect to an SMTP server. In this way, the
application is totally insulated from changes in the email server configuration environment -
it simply asks for, and receives, a preconfigured session whenever needed.

The steps required for this are outlined below.

1. Declare Your Resource Requirements

The first thing you should do is modify the web application deployment descriptor (/WEB-
INF/web.xml) to declare the JNDI name under which you will look up preconfigured
sessions. By convention, all such names should resolve to the mail subcontext (relative to
the standard java:comp/env naming context that is the root of all provided resource
factories. A typical web.xml entry might look like this:

<resource-ref>
<description>
Resource reference to a factory for javax.mail.Session
instances that may be used for sending electronic mail
messages, preconfigured to connect to the appropriate
SMTP server.
</description>
<res-ref-name>
mail/Session
</res-ref-name>
<res-type>
javax.mail.Session
</res-type>
<res-auth>
Container
</res-auth>
</resource-ref>

WARNING - Be sure you respect the element ordering that is required by the DTD for web
application deployment descriptors! See the Servlet Specification for details.

2. Code Your Application's Use Of This Resource

A typical use of this resource reference might look like this:

Context initCtx = new InitialContext();


Context envCtx = (Context) initCtx.lookup("java:comp/env");
Session session = (Session) envCtx.lookup("mail/Session");

Message message = new MimeMessage(session);


message.setFrom(new InternetAddress(request.getParameter("from")));
InternetAddress to[] = new InternetAddress[1];
to[0] = new InternetAddress(request.getParameter("to"));
message.setRecipients(Message.RecipientType.TO, to);
message.setSubject(request.getParameter("subject"));
message.setContent(request.getParameter("content"), "text/plain");
Transport.send(message);

Note that the application uses the same resource reference name that was declared in the
web application deployment descriptor. This is matched up against the resource factory that
is configured in the <Context> element for the web application as described below.

3. Configure Tomcat's Resource Factory

To configure Tomcat's resource factory, add an elements like this to the <Context> element
for this web application.

<Context ...>
...
<Resource name="mail/Session" auth="Container"
type="javax.mail.Session"
mail.smtp.host="localhost"/>
...
</Context>

Note that the resource name (here, mail/Session) must match the value specified in the
web application deployment descriptor. Customize the value of
the mail.smtp.host parameter to point at the server that provides SMTP service for your
network.

Additional resource attributes and values will be converted to properties and values and
passed to javax.mail.Session.getInstance(java.util.Properties) as part of
the java.util.Properties collection. In addition to the properties defined in Annex A of
the JavaMail specification, individual providers may also support additional properties.

Tomcat's resource factory provides a password property which can be configured by


adding password="yourpassword" to the Resource definition.

4. Install the JavaMail libraries

Download the JavaMail API. The JavaMail API requires the Java Activation Framework
(JAF) API as well. The Java Activation Framework is included in Java SE 6 onwards. Java
SE 5 users can download the latest version, JAF 1.1.1.

Unpackage the distribution(s) and place mail.jar (and activation.jar if required) into
$CATALINA_HOME/lib so the JAR(s) is(are) available to Tomcat during the initialization
of the mail Session Resource. Note: placing jars in both $CATALINA_HOME/lib and a
web application's lib folder will cause an error, so ensure mail.jar (and activation.jar) is(are)
placed only the $CATALINA_HOME/lib location.

Example Application

The /examples application included with Tomcat contains an example of utilizing this
resource factory. It is accessed via the "JSP Examples" link. The source code for the servlet
that actually sends the mail message is in /WEB-INF/classes/SendMailServlet.java.

WARNING - The default configuration assumes that there is an SMTP server listing on
port 25 on localhost. If this is not the case, edit the <Context> element for this web
application and modify the parameter value for the mail.smtp.host parameter to be the
host name of an SMTP server on your network.
JDBC Data Sources
0. Introduction

Many web applications need to access a database via a JDBC driver, to support the
functionality required by that application. The J2EE Platform Specification requires J2EE
Application Servers to make available a DataSource implementation (that is, a connection
pool for JDBC connections) for this purpose. Tomcat 6 offers exactly the same support, so
that database-based applications you develop on Tomcat using this service will run
unchanged on any J2EE server.

For information about JDBC, you should consult the following:

 http://java.sun.com/products/jdbc/ - Home page for information about Java


Database Connectivity.
 http://docs.oracle.com/javase/1.3/docs/guide/jdbc/spec2/jdbc2.1.frame.html -
The JDBC 2.1 API Specification.
 http://java.sun.com/products/jdbc/jdbc20.stdext.pdf - The JDBC 2.0 Standard
Extension API (including the javax.sql.DataSource API). This package is
now known as the "JDBC Optional Package".
 http://java.sun.com/j2ee/download.html - The J2EE Platform Specification
(covers the JDBC facilities that all J2EE platforms must provide to
applications).

NOTE - The default data source support in Tomcat is based on the DBCP connection pool
from the Commons project. However, it is possible to use any other connection pool that
implements javax.sql.DataSource, by writing your own custom resource factory, as
described below.

1. Install Your JDBC Driver

Use of the JDBC Data Sources JNDI Resource Factory requires that you make an
appropriate JDBC driver available to both Tomcat internal classes and to your web
application. This is most easily accomplished by installing the driver's JAR file(s) into
the $CATALINA_HOME/lib directory, which makes the driver available both to the resource
factory and to your application.

2. Declare Your Resource Requirements

Next, modify the web application deployment descriptor (/WEB-INF/web.xml) to declare


the JNDI name under which you will look up preconfigured data source. By convention, all
such names should resolve to the jdbc subcontext (relative to the
standard java:comp/env naming context that is the root of all provided resource factories.
A typical web.xml entry might look like this:

<resource-ref>
<description>
Resource reference to a factory for java.sql.Connection
instances that may be used for talking to a particular
database that is configured in the <Context>
configurartion for the web application.
</description>
<res-ref-name>
jdbc/EmployeeDB
</res-ref-name>
<res-type>
javax.sql.DataSource
</res-type>
<res-auth>
Container
</res-auth>
</resource-ref>

WARNING - Be sure you respect the element ordering that is required by the DTD for web
application deployment descriptors! See the Servlet Specification for details.

3. Code Your Application's Use Of This Resource

A typical use of this resource reference might look like this:

Context initCtx = new InitialContext();


Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)
envCtx.lookup("jdbc/EmployeeDB");

Connection conn = ds.getConnection();


... use this connection to access the database ...
conn.close();

Note that the application uses the same resource reference name that was declared in the
web application deployment descriptor. This is matched up against the resource factory that
is configured in the <Context> element for the web application as described below.
4. Configure Tomcat's Resource Factory

To configure Tomcat's resource factory, add an element like this to the <Context> element
for the web application.

<Context ...>
...
<Resource name="jdbc/EmployeeDB"
auth="Container"
type="javax.sql.DataSource"
username="dbusername"
password="dbpassword"
driverClassName="org.hsql.jdbcDriver"
url="jdbc:HypersonicSQL:database"
maxActive="8"
maxIdle="4"/>
...
</Context>

Note that the resource name (here, jdbc/EmployeeDB) must match the value specified in the
web application deployment descriptor.

This example assumes that you are using the HypersonicSQL database JDBC driver.
Customize the driverClassName and driverName parameters to match your actual
database's JDBC driver and connection URL.

The configuration properties for Tomcat's standard data source resource factory
(org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory) are as follows:

 driverClassName - Fully qualified Java class name of the JDBC driver to be


used.
 username - Database username to be passed to our JDBC driver.
 password - Database password to be passed to our JDBC driver.
 url - Connection URL to be passed to our JDBC driver. (For backwards
compatibility, the property driverName is also recognized.)
 initialSize - The initial number of connections that will be created in the pool
during pool initialization. Default: 0
 maxActive - The maximum number of connections that can be allocated
from this pool at the same time. Default: 8
 minIdle - The minimum number of connections that will sit idle in this pool
at the same time. Default: 0
 maxIdle - The maximum number of connections that can sit idle in this pool
at the same time. Default: 8
 maxWait - The maximum number of milliseconds that the pool will wait
(when there are no available connections) for a connection to be returned
before throwing an exception. Default: -1 (infinite)

Some additional properties handle connection validation:


 validationQuery - SQL query that can be used by the pool to validate
connections before they are returned to the application. If specified, this
query MUST be an SQL SELECT statement that returns at least one row.
 validationQueryTimeout - Timeout in seconds for the validation query to
return. Default: -1 (infinite)
 testOnBorrow - true or false: whether a connection should be validated
using the validation query each time it is borrowed from the pool. Default:
true
 testOnReturn - true or false: whether a connection should be validated using
the validation query each time it is returned to the pool. Default: false

The optional evictor thread is responsible for shrinking the pool by removing any
conections which are idle for a long time. The evictor does not respect minIdle. Note that
you do not need to activate the evictor thread if you only want the pool to shrink according
to the configured maxIdle property.

The evictor is disabled by default and can be configured using the following properties:

 timeBetweenEvictionRunsMillis - The number of milliseconds between


consecutive runs of the evictor. Default: -1 (disabled)
 numTestsPerEvictionRun - The number of connections that will be
checked for idleness by the evitor during each run of the evictor. Default: 3
 minEvictableIdleTimeMillis - The idle time in milliseconds after which a
connection can be removed from the pool by the evictor. Default:
30*60*1000 (30 minutes)
 testWhileIdle - true or false: whether a connection should be validated by
the evictor thread using the validation query while sitting idle in the pool.
Default: false

Another optional feature is the removal of abandoned connections. A connection is called


abandoned if the application does not return it to the pool for a long time. The pool can
close such connections automatically and remove them from the pool. This is a workaround
for applications leaking connections.

The abandoning feature is disabled by default and can be configured using the following
properties:

 removeAbandoned - true or false: whether to remove abandoned


connections from the pool. Default: false
 removeAbandonedTimeout - The number of seconds after which a
borrowed connection is assumed to be abandoned. Default: 300
 logAbandoned - true or false: whether to log stack traces for application
code which abandoned a statement or connection. This adds serious
overhead. Default: false

Finally there are various properties that allow further fine tuning of the pool behaviour:

 defaultAutoCommit - true or false: default auto-commit state of the


connections created by this pool. Default: true
 defaultReadOnly - true or false: default read-only state of the connections
created by this pool. Default: false
 defaultTransactionIsolation - This sets the default transaction isolation
level. Can be one
of NONE, READ_COMMITTED, READ_UNCOMMITTED, REPEATABLE_READ, SERIAL
IZABLE. Default: no default set
 poolPreparedStatements - true or false: whether to pool
PreparedStatements and CallableStatements. Default: false
 maxOpenPreparedStatements - The maximum number of open statements
that can be allocated from the statement pool at the same time. Default: -1
(unlimited)
 defaultCatalog - The name of the default catalog. Default: not set
 connectionInitSqls - A list of SQL statements run once after a Connection is
created. Separate multiple statements by semicolons (;). Default: no
statement
 connectionProperties - A list of driver specific properties passed to the
driver for creating connections. Each property is given as name=value,
multiple properties are separated by semicolons (;). Default: no properties
 accessToUnderlyingConnectionAllowed - true or false: whether accessing
the underlying connections is allowed. Default: false

For more details, please refer to the commons-dbcp documentation.


Adding Custom Resource Factories
If none of the standard resource factories meet your needs, you can write your own factory
and integrate it into Tomcat 6, and then configure the use of this factory in
the <Context> element for the web application. In the example below, we will create a
factory that only knows how to create com.mycompany.MyBean beans from the Generic
JavaBean Resources example above.

1. Write A Resource Factory Class

You must write a class that implements the JNDI service


provider javax.naming.spi.ObjectFactory inteface. Every time your web application
calls lookup() on a context entry that is bound to this factory,
the getObjectInstance() method is called, with the following arguments:

 Object obj - The (possibly null) object containing location or reference


information that can be used in creating an object. For Tomcat, this will
always be an object of type javax.naming.Reference, which contains the
class name of this factory class, as well as the configuration properties (from
the <Context> for the web application) to use in creating objects to be
returned.
 Name name - The name to which this factory is bound relative to nameCtx,
or null if no name is specified.
 Context nameCtx - The context relative to which the name parameter is
specified, or null if name is relative to the default initial context.
 Hashtable environment - The (possibly null) environment that is used in
creating this object. This is generally ignored in Tomcat object factories.

To create a resource factory that knows how to produce MyBean instances, you might create
a class like this:

package com.mycompany;

import java.util.Enumeration;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;

public class MyBeanFactory implements ObjectFactory {

public Object getObjectInstance(Object obj,


Name name2, Context nameCtx, Hashtable environment)
throws NamingException {

// Acquire an instance of our specified bean class


MyBean bean = new MyBean();

// Customize the bean properties from our attributes


Reference ref = (Reference) obj;
Enumeration addrs = ref.getAll();
while (addrs.hasMoreElements()) {
RefAddr addr = (RefAddr) addrs.nextElement();
String name = addr.getType();
String value = (String) addr.getContent();
if (name.equals("foo")) {
bean.setFoo(value);
} else if (name.equals("bar")) {
try {
bean.setBar(Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new NamingException("Invalid 'bar' value " +
value);
}
}
}

// Return the customized instance


return (bean);

In this example, we are unconditionally creating a new instance of


the com.mycompany.MyBean class, and populating its properties based on the parameters
included in the <ResourceParams> element that configures this factory (see below). You
should note that any parameter named factory should be skipped - that parameter is used to
specify the name of the factory class itself (in this case, com.mycompany.MyBeanFactory)
rather than a property of the bean being configured.

For more information about ObjectFactory, see the JNDI 1.2 Service Provider Interface
(SPI) Specification.

You will need to compile this class against a class path that includes all of the JAR files in
the $CATALINA_HOME/lib directory. When you are through, place the factory class (and the
corresponding bean class) unpacked under $CATALINA_HOME/lib, or in a JAR file
inside $CATALINA_HOME/lib. In this way, the required class files are visible to both Catalina
internal resources and your web application.

2. Declare Your Resource Requirements

Next, modify your web application deployment descriptor (/WEB-INF/web.xml) to declare


the JNDI name under which you will request new instances of this bean. The simplest
approach is to use a <resource-env-ref> element, like this:

<resource-env-ref>
<description>
Object factory for MyBean instances.
</description>
<resource-env-ref-name>
bean/MyBeanFactory
</resource-env-ref-name>
<resource-env-ref-type>
com.mycompany.MyBean
</resource-env-ref-type>
</resource-env-ref>

WARNING - Be sure you respect the element ordering that is required by the DTD for web
application deployment descriptors! See the Servlet Specification for details.

3. Code Your Application's Use Of This Resource

A typical use of this resource environment reference might look like this:

Context initCtx = new InitialContext();


Context envCtx = (Context) initCtx.lookup("java:comp/env");
MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");

writer.println("foo = " + bean.getFoo() + ", bar = " +


bean.getBar());

4. Configure Tomcat's Resource Factory

To configure Tomcat's resource factory, add an elements like this to the <Context> element
for this web application.

<Context ...>
...
<Resource name="bean/MyBeanFactory" auth="Container"
type="com.mycompany.MyBean"
factory="com.mycompany.MyBeanFactory"
bar="23"/>
...
</Context>

Note that the resource name (here, bean/MyBeanFactory must match the value specified in
the web application deployment descriptor. We are also initializing the value of
the bar property, which will cause setBar(23) to be called before the new bean is returned.
Because we are not initializing the foo property (although we could have), the bean will
contain whatever default value is set up by its constructor.

You will also note that, from the application developer's perspective, the declaration of the
resource environment reference, and the programming used to request new instances, is
identical to the approach used for the Generic JavaBean Resources example. This illustrates
one of the advantages of using JNDI resources to encapsulate functionality - you can change
the underlying implementation without necessarily having to modify applications using the
resources, as long as you maintain compatible APIs.
Non-DBCP Solutions
These solutions either utilise a single connection to the database (not recommended for
anything other than testing!) or some other pooling technology.
Oracle 8i with OCI client
Introduction
Whilst not strictly addressing the creation of a JNDI DataSource using the OCI client, these
notes can be combined with the Oracle and DBCP solution above.

In order to use OCI driver, you should have an Oracle client installed. You should have
installed Oracle8i(8.1.7) client from cd, and download the suitable JDBC/OCI
driver(Oracle8i 8.1.7.1 JDBC/OCI Driver) from otn.oracle.com.

After renaming classes12.zip file to classes12.jar for Tomcat, copy it


into $CATALINA_HOME/lib. You may also have to remove the javax.sql.* classes from
this file depending upon the version of Tomcat and JDK you are using.
Putting it all together
Ensure that you have the ocijdbc8.dll or .so in
your $PATH or LD_LIBRARY_PATH (possibly in $ORAHOME\bin) and also confirm that the
native library can be loaded by a simple test program
using System.loadLibrary("ocijdbc8");

You should next create a simple test servlet or jsp that has these critical lines:
DriverManager.registerDriver(new
oracle.jdbc.driver.OracleDriver());
conn =
DriverManager.getConnection("jdbc:oracle:oci8:@database","username","pas
sword");

where database is of the form host:port:SID Now if you try to access the URL of your test
servlet/jsp and what you get is a ServletException with a root cause
of java.lang.UnsatisfiedLinkError:get_env_handle.

First, the UnsatisfiedLinkError indicates that you have

 a mismatch between your JDBC classes file and your Oracle client version.
The giveaway here is the message stating that a needed library file cannot be
found. For example, you may be using a classes12.zip file from Oracle
Version 8.1.6 with a Version 8.1.5 Oracle client. The classeXXXs.zip file and
Oracle client software versions must match.
 A $PATH, LD_LIBRARY_PATH problem.
 It has been reported that ignoring the driver you have downloded from otn
and using the classes12.zip file from the directory $ORAHOME\jdbc\lib will
also work.

Next you may experience the error ORA-06401 NETCMN: invalid driver designator

The Oracle documentation says : "Cause: The login (connect) string contains an invalid
driver designator. Action: Correct the string and re-submit." Change the database connect
string (of the form host:port:SID) with this
one: (description=(address=(host=myhost)(protocol=tcp)(port=1521))
(connect_data=(sid=orcl)))

Ed. Hmm, I don't think this is really needed if you sort out your TNSNames - but I'm not an
Oracle DBA :-)
Common Problems
Here are some common problems encountered with a web application which uses a database
and tips for how to solve them.

Intermittent Database Connection Failures


Tomcat runs within a JVM. The JVM periodically performs garbage collection (GC) to
remove java objects which are no longer being used. When the JVM performs GC execution
of code within Tomcat freezes. If the maximum time configured for establishment of a
database connection is less than the amount of time garbage collection took you can get a
database connection failure.

To collect data on how long garbage collection is taking add the -verbose:gc argument to
your CATALINA_OPTS environment variable when starting Tomcat. When verbose gc is
enabled your $CATALINA_BASE/logs/catalina.out log file will include data for every
garbage collection including how long it took.
When your JVM is tuned correctly 99% of the time a GC will take less than one second. The
remainder will only take a few seconds. Rarely, if ever should a GC take more than 10
seconds.

Make sure that the db connection timeout is set to 10-15 seconds. For the DBCP you set this
using the parameter maxWait.
Random Connection Closed Exceptions
These can occur when one request gets a db connection from the connection pool and closes
it twice. When using a connection pool, closing the connection just returns it to the pool for
reuse by another request, it doesn't close the connection. And Tomcat uses multiple threads
to handle concurrent requests. Here is an example of the sequence of events which could
cause this error in Tomcat:

Request 1 running in Thread 1 gets a db connection.

Request 1 closes the db connection.

The JVM switches the running thread to Thread 2

Request 2 running in Thread 2 gets a db connection


(the same db connection just closed by Request 1).

The JVM switches the running thread back to Thread 1

Request 1 closes the db connection a second time in a finally block.

The JVM switches the running thread back to Thread 2

Request 2 Thread 2 tries to use the db connection but fails


because Request 1 closed it.

Here is an example of properly written code to use a database connection obtained from a
connection pool:

Connection conn = null;


Statement stmt = null; // Or PreparedStatement if needed
ResultSet rs = null;
try {
conn = ... get connection from connection pool ...
stmt = conn.createStatement("select ...");
rs = stmt.executeQuery();
... iterate through the result set ...
rs.close();
rs = null;
stmt.close();
stmt = null;
conn.close(); // Return to connection pool
conn = null; // Make sure we don't close it twice
} catch (SQLException e) {
... deal with errors ...
} finally {
// Always make sure result sets and statements are closed,
// and the connection is returned to the pool
if (rs != null) {
try { rs.close(); } catch (SQLException e) { ; }
rs = null;
}
if (stmt != null) {
try { stmt.close(); } catch (SQLException e) { ; }
stmt = null;
}
if (conn != null) {
try { conn.close(); } catch (SQLException e) { ; }
conn = null;
}
}

Context versus GlobalNamingResources


Please note that although the above instructions place the JNDI declarations in a Context
element, it is possible and sometimes desirable to place these declarations in
the GlobalNamingResources section of the server configuration file. A resource placed in the
GlobalNamingResources section will be shared among the Contexts of the server.
JNDI Resource Naming and Realm Interaction
In order to get Realms to work, the realm must refer to the datasource as defined in the
<GlobalNamingResources> or <Context> section, not a datasource as renamed using
<ResourceLink>

You might also like