Creating own JNDI DataSource
Yesterday, I was having lot of troubles loading DataSource via JNDI in my tests. At first I tried to load just the InitialContext, and bind something. I used MysqlDataSource provided directly by the MySQL ConnectorJ library. There is the code:
MysqlDataSource ds = new MysqlDataSource();
ds.setUrl(url);
ds.setUser(user);
ds.setPassword(password);
ds.setUseUnicode(true);
ds.setCharacterSetResults("UTF-8");
ic.bind("java:/comp/env/ds/test", ds);
This apparently didn’t work. This is a very typical access when some programmer tries to get things working via some API, but doesn’t have any clue about what is he doing. Very typical. [-; So I had to do some research (read programmer’s research which is basically looking for some code or tutorial to get things working). So I found that for every path in JNDI I want to bind some object, I will need to create this path. Hm, ok. So there is the code for creating a new path (= subcontext).
InitialContext ic = new InitialContext();
ic.createSubcontext("java:");
ic.createSubcontext("java:/comp");
ic.createSubcontext("java:/comp/env");
ic.createSubcontext("java:/comp/env/test");
Hm, still nothing. At the second line in the previous code, JNDI code threw NoInitialContextException exception. I didn’t have any context factory defined. Where should I get it?! At first I thought I will need to use some Spring or some similar beast which I was scared of, but as I turned out, it was much simpler. I just needed to rip Apache Tomcat and use their own provider.
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory"); System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
Also don’t forget to add two jars to the test classpath. These jars are available at tomcat/bin/tomcat-juli.jar and tomcat/lib/catalina.jar. And that’s it. So the final code follows:
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/test");
MysqlDataSource ds = new MysqlDataSource();
ds.setUrl(url);ds.setUser(user);
ds.setPassword(password);
ds.setUseUnicode(true);
ds.setCharacterSetResults("UTF-8");
ic.bind("java:/comp/env/ds/cms", ds);
Also last note. Never forget to use useUnicode and characterSetResults set to UTF-8 properties of Mysql driver with unicode tables, or your data will be crippled.





