How to use JNDI DataSource provided by Tomcat in Spring?
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:
- Tomcat 8 JNDI Datasource HOW-TO
- Tomcat 8 Context Resource Links Reference
- Spring 4 JEE JNDI Lookup XML Schema Reference
- Spring 4 JndiObjectFactoryBean Javadoc
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.
With Spring's JavaConfig mechanism, you can do it like so:
@Configurationpublic class MainConfig { ... @Bean DataSource dataSource() { DataSource dataSource = null; JndiTemplate jndi = new JndiTemplate(); try { dataSource = jndi.lookup("java:comp/env/jdbc/yourname", DataSource.class); } catch (NamingException e) { logger.error("NamingException for java:comp/env/jdbc/yourname", e); } return dataSource; }}
Assuming you have a "sampleDS" datasource definition inside your tomcat configuration, you can add following lines to your applicationContext.xml
to access the datasource using JNDI.
<jee:jndi-lookup expected-type="javax.sql.DataSource" id="springBeanIdForSampleDS" jndi-name="sampleDS"/>
You have to define the namespace and schema location for jee
prefix using:
xmlns:jee="http://www.springframework.org/schema/jee"xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"