Toplink and JNDI configuration on Glassfish and Tomcat

JNDI setup and configuration is one of those parts of java where the differences between container implementations are just enough to be a barrier to porting your application to a different server. This combined with the incompatibilities with JPA between implementations can lead to vendor or stack lock-in, hopefully this get better with the next release of JPA.

One of the issues with JPA is using JNDI datasources for your persistenceContext.

Glassfish JNDI setup and persistence.xml

Glassfish does not require any special handlng for its JNDI entry.

1) To setup the entry log in to the admin console and then go to resources->JDBC->connection Pools and add a new connection pool for your database. The wizard will take you through the two step process. One the second form of the wizard don't forget to scroll to the bottom and fill out the database details. When you are finished save the connection.

2) Next go to JDBC Resources and add the JNDI entry. It is customary to add the JNDI entry as jdbc/<name>. When adding the entry select the connection pool you just setup in step 1.

3) In your persistence.xml file make sure that the <non-jta-datasource> or <jta-datasource> had a text node of only "jdbc/<name>".

Once this is done your application should be able to use the datasource without any problems.

Tomcat JNDI setup and persistence.xml

For Tomcat things are slightly more complicated.

 1) Login to the tomcat admin application. This may need to be installed separatly. If you using Ubuntu its "apt-get install tomcat5.5-admin". You will also have to edit the tomcat-users.xml file and assign the manager and admin roles to one of the users. This is usually the tomcat user on dev environments.

2) There are several ways to setup the JNDI datasource:

a) Go to the Resources->Datasources and add a datasource. The entry is not complicated and looks something like:

    JNDI Name:jdbc/<name>
    DataSource URL: jdbc:mysql://127.0.0.1/openbill
    Driver: com.mysql.jdbc.Driver
    Username: root
    Password: password

 Next you need to edit the web.xml file of the application to reference this global resource. 

        <ResourceLink global="jdbc/<name>" name="jdbc/<name>" type="com.mysql.jdbc.Driver"/>

b) To avoid this step you can simply add the datasource to the context of the web application. The easiest way to do this is with the Admin application under tomcat server->service->host and then your applications context.

c) Alternatively you can provide a META-INF/context.xml file with the settings so the connection is automatically created when the application is deployed.

<Resource name="jdbc/<name>" auth="Container"
  type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000"
removeAbandoned="true" username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1/<database>?autoReconnect=true&amp;useUnicode=true"
removeAbandonedTimeout="60" logAbandoned="true"/>

 3) Next you need to edit the persistence.xml file. The important step is to make sure the  <non-jta-datasource> or <jta-datasource> entry has the following "java:comp/env/jdbc/openbillds" as its text node. Note the additional keys on the JNDI entry.

4) For Toplink you also need to setup a session customizer. Under the properties section of the persistence,..xml file add the following:

       <property name="toplink.session.customizer" value="<package>.ToplinkSessionCustomiser"/>


You then need to create a class that extends the SessionCustomizer. Put he following class in a convenient package:

import oracle.toplink.essentials.sessions.Session;
import oracle.toplink.essentials.tools.sessionconfiguration.SessionCustomizer;
import oracle.toplink.essentials.jndi.JNDIConnector;

public class ToplinkSessionCustomiser implements SessionCustomizer{
    public void customize(Session session) throws Exception {
            JNDIConnector connector = (JNDIConnector) session.getLogin().getConnector();
            connector.setLookupType(JNDIConnector.STRING_LOOKUP);
    }
}