Thursday, April 26, 2012

Accessing your database with JNDI

For those not familiar with Java Naming and Directory Interface (JNDI), it's a mechanism in Java for looking up named "things", which can be anything you want. How it works is you define something on the server (for this blog entry, it's a data source for accessing a database), give it a name, and then you can retrieve this object in your application to perform some task with it (such as, use the data source to connect to a database). Not all runtime environments have a JNDI environment defined; batch Java typically doesn't, but application servers do (so use JNDI with your service but not with your program).

When developing a SQL application, there are two main benefits to this design:
  • The application doesn't need to know how to get to the database.
  • Most data sources support connection pooling, which has significant performance improvements over always obtaining a new connection in your application.
There are two types of authentication for JNDI:
  • Container-based: the credentials are stored in the JNDI definition on the server and applications do not provide any credentials. This is the most common choice, and thus the default setting.
  • Application-based: the application must provide the credentials.
    Note: Not all data sources support application-based authentication! Apache Tomcat's default data source implementation, for example, will throw an error if you try to use it.
So, how do you use JNDI in your EDT application? The best way is to use a resource binding. By default, we will enable JNDI for the SQL resource binding:

The JDNI settings are visible when you select an SQL resource binding in the Deployment Descriptor editor. You can change the name of the data source of the type of authentication that will be used.

The code that you write does not care how the connection is being obtained, those details are left to the deployment descriptor. A quick snippet for connecting to a database and adding a new row:

ds SQLDataSource = SysLib.getResource("binding:DerbyConnection");
add newRecord to ds;

Normally the JNDI configuration in your deployment descriptor is only used by the client application for obtaining the data source from the server, however if you are deploying to Apache Tomcat then we will also define the data source for you. If you are deploying to any other server type, you will need to define the data source on the server yourself (refer to the server's documentation for how this should be done). The reason we cannot do this for any type of server is that there is no standard for how to define the data source, the standard only covers how to access defined objects; every server does it differently.

I'll leave you with a tip: the IDE test server does support JNDI, but if you want to add connection pooling support to it then all you need to do is define an Apache Tomcat runtime at Window > Preferences > Server > Runtime Environments to take advantage of Tomcat's connection pooling support.


No comments:

Post a Comment