Injecting JNDI datasources for JUnit Tests outside of a container
I was working on some webservices that we're moving into libraries the other day, and needed to run a full set of tests using junit, but outside of a container. I didn't want to create and deploy an entire test harness, I just wanted to run the junit tests in the nb ide. But I couldn't get the test to inject the datasource resource so it was usable.
I finally got it working, but I'll spare you all the pain I went through to get here. Here's how I did it in my test class:
@BeforeClass
public static void setUpClass() throws Exception {
// rcarver - setup the jndi context and the datasource
try {
// Create initial context
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES,
"org.apache.naming");
InitialContext ic = new InitialContext();
ic.createSubcontext("java:");
ic.createSubcontext("java:/comp");
ic.createSubcontext("java:/comp/env");
ic.createSubcontext("java:/comp/env/jdbc");
// Construct DataSource
OracleConnectionPoolDataSource ds = new OracleConnectionPoolDataSource();
ds.setURL("jdbc:oracle:thin:@host:port:db");
ds.setUser("MY_USER_NAME");
ds.setPassword("MY_USER_PASSWORD");
ic.bind("java:/comp/env/jdbc/nameofmyjdbcresource", ds);
} catch (NamingException ex) {
Logger.getLogger(MyDAOTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
As you can see, in this case I used the OracleConnectionPoolDataSource, you should use the datasource for your db connection. Don't forget to link in the appropriate db jar (in my case it was ojdbc14.jar)
The code that is used to retrieve the datasource (which works for test and production) looks like this:
Context initContext = new InitialContext();
Context webContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource) webContext.lookup("jdbc/nameofmyjdbcresource");
viola!

Thank you so much for posting this! After searching for several days I finally found exactly what I was looking for. I just had to change two lines since I'm using SQL Server.
SQLServerConnectionPoolDataSource ds = new SQLServerConnectionPoolDataSource();
ds.setURL("jdbc:sqlserver://host:1433;databaseName=db");
Greate job!
Posted by Matt on March 20, 2008 at 04:30 PM MDT #
I needed to add the bootstrap.jar from my tomcat/bin directory and then it works well.
Thanks.
Posted by Hein on April 22, 2008 at 06:58 AM MDT #
Wow! You deserve a medal! This was an extremely helpful post that I will be sharing with my co-workers. Thanks!
Posted by Jeff on May 28, 2008 at 11:04 AM MDT #
Hey,
Thanks for these good tips!
I've done that
I have 3 different environnements: weblogic in production, tomcat for local testing, and i also would like to test some code in the webapp using JUnit.
I manage to get the DataSource, but, when I try to get the Connection, I have an strange SQLException:
I/O Exception : The Network Adapter could not establish the connection
I can't see why? Anyone with an idea?
Thanks a lot.
Posted by Johan Chouquet on July 10, 2008 at 07:18 AM MDT #
Randy,
Thank you for the out-of-container SE JNDI code above.
It works perfectly, I have referenced your blog on one of our tutorials on running JPA/EJB 3.0 on Tomcat 6 - when developers want to reuse the JNDI datasource.
thank you
/michael
Posted by Michael OBrien on August 14, 2008 at 08:37 AM MDT #
I too needed this, but for Spring implementation, I took some of yours and expanded it to deal with my Spring need - not sure where to post it, but this seems as good as any :)
Test class
@BeforeClass
public static void setUpClass() throws Exception
{
try
{
// Create initial context
System.setProperty( Context.INITIAL_CONTEXT_FACTORY,
"org.apache.xbean.spring.jndi.SpringInitialContextFactory" );
//-- Loads initial context - and data found in jndi.xml
new InitialContext();
}
catch( NamingException ex )
{
ex.printStackTrace();
//Logger.getLogger( AbstractTest.class.getName() ).log( Priority.SEVERE, null, ex );
}
jndi.xml:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean
id="jndi"
class="org.apache.xbean.spring.jndi.DefaultContext">
<property name="entries">
<map>
<entry key="jdbc/MyDataSource">
<bean
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
destroy-method="close"
singleton="false">
<property
name="driverClassName"
value="com.ibm.db2.jcc.DB2Driver" />
<property
name="url"
value="jdbc:db2://xxx.xxx.xxx.xxx:50000/DB2B" />
<property
name="username"
value="joebob" />
<property
name="password"
value="wilson" />
<property name="connectionProperties">
<map>
<entry
key="currentSchema"
value="schemajoe" />
<entry
key="retrieveMessagesFromServerOnGetMessage"
value="true" />
</map>
</property>
</bean>
</entry>
</map>
</property>
</bean>
</beans>
The class listed above for org.apache.xbean.spring.jndi.SpringInitialContextFactory
comes from http://geronimo.apache.org/xbean/
The only reason I chose this route is because of the schema piece - and I wanted to stay in Spring.
Posted by Sean on December 11, 2008 at 04:25 PM MST #
Hi Randy,
a big THANK YOU from me as well. You saved my day.
regards,
se
Posted by se on May 09, 2009 at 03:35 PM MDT #
Very helpful. Thank you Randy for posting this!
Cheers,
Freddy
Posted by Freddy Daoud on May 21, 2009 at 12:27 PM MDT #
Thanks a lot, this helped a lot.
We just Maven. First I got a classnotfound error. I needed to add extra dependencies need.
Below are the dependencies. For unit tests, of course you can use the test scope. I couldn't use the xml of the original pom.xml file, because HTML syntax is not allowed in comments.
artifactId: naming-factory
version: 5.5.15
groupId: tomcat
artifactId: naming-resources
version: 5.5.15
groupId: tomcat
Posted by Gerbrand van Dieijen on May 25, 2009 at 08:35 AM MDT #