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!
Comments:

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 #

Post a Comment:
  • HTML Syntax: NOT allowed

This blog copyright 2009 by Randy Carver