Setting up a datasource in JNDI
Writing code quite often involves writing a lot of unit tests. If your tests cover isolated business logic (standard unit tests) writing tests is usually pretty easy. No big dependencies and very isolated testing. If you are writing tests involving database connections things can get a little more complex. The datasource in an application context is usually stored in JNDI so you need to initialize this yourself when writing tests. I use simple-jndi for this and this is how I do it.
First you need to get the jars from simple-jndi. If you use Maven you can also just add this to your pom.xml.
<dependency>
<groupId>simple-jndi</groupId>
<artifactId>simple-jndi</artifactId>
<version>0.11.4.1</version>
<scope>test</scope>
</dependency>
Initialization of the datasource is done by creating the context and adding the datasource to the context. The context can be defined in the file system (by using the SimpleContextFactory) or you can just store it in memory (by using the MemoryContextFactory). In this example I initialize a datasource for the HSQLDB database, store it in memory and make the context available for all occurrences of the initial contexts by setting the system property org.osjava.sj.jndi.shared to true.
import javax.naming.Context;
import javax.naming.InitialContext;
import org.hsqldb.jdbc.JDBCDataSource;
...
// Create initial context
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.osjava.sj.memory.MemoryContextFactory");
System.setProperty("org.osjava.sj.jndi.shared", "true");
InitialContext ic = new InitialContext();
ic.createSubcontext("java:/comp/env/jdbc");
// Construct DataSource
JDBCDataSource ds = new JDBCDataSource();
ds.setDatabase("jdbc:hsqldb:hsql://localhost/xdb");
ds.setUser("SA");
ds.setPassword("");
// Put datasource in JNDI context
ic.bind("java:/comp/env/jdbc/myDS", ds);
This creates a HSQLDB datasource in the context java:/comp/env/jdbc/myDS. The datasource can be retrieved from the code by looking it up in the context like this.
InitialContext ic = new InitialContext();
ds = (DataSource)ic.lookup("java:/comp/env/jdbc/myDS");
It is as easy as that. Now you can access your database via JNDI.
From the original comments
Preserved from the old Disqus thread when the blog moved to giscus.
Michael Prescott · 2013-04-08 Yes, extremely useful. Simple-JNDI's advice to use jndi.properties is terrible as it forces you to figure out how to reconcile it with whatever else you've got going on with Maven. This is much, much nicer. Thanks!
Holger Thurow · 2017-01-15 Simple-JNDI is not under active development anymore. Because I found some issues concerning shared contexts (especially using datasources), I decided to branch the original project and add some new features. There is now a 0.12.0 you can find here: github.com/h-thurow/Simple-JNDI.
Bowei Ma · 2017-12-10 Do you make enough tests on the latest version? I'm looking for a JNDI implementation now.
Holger Thurow · 2017-12-10 You can inspect all tests in github.com/h-thurow/Simple-JNDI. There are about 180 tests. The JNDI specification is not fully implemented, but seems to satisfy common requirements as there are no open bugs. There is also an alternative with TomcatJNDI that offers a full-fledged JNDI implementation. Which one to choose depends on your needs and preferences.
Comments