Lovegiver
Lovegiver

Reputation: 451

How to make use of a DataSource via JNDI works?

there's some things I definitely don't understand while using JNDI.

This should simplify our Java developers' life, but this promise sounds false.

The simplest way tu use a database from within an application seems to build each time you need it (so, once per application) a datasource class giving you a connection or session you will use. It's a tool class written in a few minutes where you have to declare the driver, url, login and password. And it's done.

The recommanded way is to rely on the server resources management, JNDI and all resources such as directory, etc. But is it really usefull and simple ??

With Tomcat, you have to have to fully describe the datasource in server.xml, then declare it as a resource in context.xml.

server.xml

<GlobalNamingResources>
   <Resource auth="Container" driverClassName="org.postgresql.Driver" maxIdle="30" maxTotal="100" maxWaitMillis="10000" name="jdbc/dsTriasEmployees" password="pwd" type="javax.sql.DataSource" url="jdbc:postgresql://localhost:5432/trias_employees" username="login"/>
</GlobalNamingResources>

context.xml

<ResourceLink name="jdbc/dsTriasEmployees" global="jdbc/dsTriasEmployees"
        type="javax.sql.DataSource" />

Java side, you should be able to inject it thanks to a Context Lookup code ou a @Resource(mappedBy...) annotation.

DataSource datasource;

    public Connection connectJNDI() {
        try {
            Context initContext = new InitialContext();
            Context envContext = (Context) initContext.lookup("java:/comp/env");
            datasource = (DataSource) envContext.lookup("jdbc/trias_employees");
            Connection con = datasource.getConnection();
            genericLogger.info("JNDI LOOKUP -> " + con);
            return con;
        } catch (Exception ex) {
            genericLogger.error("JNDI LOOKUP -> " + ex);

        return null;
    }

But after doing that, you still have to deal with error messages telling you that it's not enough just like this one :

javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial

I have read somewhere that I now should add a JNDI properties file and a declaration in the web.xml file like this :

web.xml

<resource-ref>
      <description>
        DB PostgreSQL
      </description>
      <res-ref-name>
        jdbc/trias_employees
      </res-ref-name>
      <res-type>
        javax.sql.DataSource
      </res-type>
      <res-auth>
        Container
      </res-auth>
</resource-ref>

But when I wanna test with jUnit, my web.xml is not usefull...

How many XML and properties files should I write just to respect the best practice that want me to delegate access to the datasource to the server ? How many times will I have to duplicate all the informations related to url, pool connection, etc. ??

I've read 2 or 3 books on Java EE, 50 posts on StackOverFlow and dozens of forums and all the JNDI Resources HOW-TO on the Tomcat website. But it still does not work...

Is there somewhere the full description of all I have to do to connect to my database using the JNDI process ?

Help me please, or I'll kill a kitten for each more minute I'm losing just to do my job in "the recommanded way".

Thanx by advance.

Upvotes: 1

Views: 1167

Answers (1)

Holger Thurow
Holger Thurow

Reputation: 824

To test classes dependent on a DataSource or any other object provided by Tomcat via JNDI outside of Tomcat you could rely on TomcatJNDI. Point it to your server.xml and context.xml and it will initialize a JNDI environment with all the objects configured in the files.

TomcatJNDI tomcatJNDI = new TomcatJNDI();
tomcatJNDI.processServerXml(serverXmlFile)
tomcatJNDI.processContextXml(contextXmlFile);
tomcatJNDI.start();

Then lookup the datasource

DataSource ds = (DataSource) InitialContext.doLookup("java:comp/env/jdbc/trias_employee")

You can find out more about TomcatJNDI here.

Upvotes: 1

Related Questions