Java – How to use JNDI DataSource provided by Tomcat in Spring

datasourcejavajndispringtomcat

It is said that in the Spring javadoc article about DriverManagerDataSource class, that this class is very simple and that it is recommended

to use a JNDI DataSource provided by the container. Such a DataSource can be exposed as a DataSource bean in a Spring ApplicationContext via JndiObjectFactoryBean

The question is: how do I accomplish this?

For example, if I wish to have DataSource bean to access my custom MySQL database, what would I require then? What should I write in the context configuration, etc?

Best Answer

If using Spring's XML schema based configuration, setup in the Spring context like this:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
...
<jee:jndi-lookup id="dbDataSource"
   jndi-name="jdbc/DatabaseName"
   expected-type="javax.sql.DataSource" />

Alternatively, setup using simple bean configuration like this:

<bean id="DatabaseName" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/DatabaseName"/>
</bean>

You can declare the JNDI resource in tomcat's server.xml using something like this:

<GlobalNamingResources>
    <Resource name="jdbc/DatabaseName"
              auth="Container"
              type="javax.sql.DataSource"
              username="dbUser"
              password="dbPassword"
              url="jdbc:postgresql://localhost/dbname"
              driverClassName="org.postgresql.Driver"
              initialSize="20"
              maxWaitMillis="15000"
              maxTotal="75"
              maxIdle="20"
              maxAge="7200000"
              testOnBorrow="true"
              validationQuery="select 1"
              />
</GlobalNamingResources>

And reference the JNDI resource from Tomcat's web context.xml like this:

  <ResourceLink name="jdbc/DatabaseName"
   global="jdbc/DatabaseName"
   type="javax.sql.DataSource"/>

Reference documentation:

Edit: This answer has been updated for Tomcat 8 and Spring 4. There have been a few property name changes for Tomcat's default datasource resource pool setup.

Related Topic