JNDI for naming databases


Reference

The JDBC 2.0 Optional Package (formerly the JDBC 2.0 Standard Extension API), Chapter 5, “JNDI and the JDBC API.”


Related interfaces

This feature provides JDBC clients with an alternative to the standard approach for obtaining database connections. Instead of invoking Class.forName (“com.sybase.jdbc3.jdbc.SybDriver”), then passing a JDBC URL to the DriverManager's getConnection( ) method, clients can access a JNDI name server using a logical name to retrieve a javax.sql.DataSource object. This object is responsible for loading the driver and establishing the connection to the physical database it represents. The client code is simpler and reusable because the vendor-specific information has been placed within the DataSource object.

The Sybase implementation of the DataSource object is com.sybase.jdbcx.SybDataSource (see the javadocs for details). This implementation supports the following standard properties using the design pattern for JavaBean components:

NoteroleName is not supported.

jConnect provides an implementation of the javax.naming.spi.ObjectFactory interface so the DataSource object can be constructed from the attributes of a name server entry. When given a javax.naming.Reference, or a javax.naming.Name and a javax.naming.DirContext, this factory can construct com.sybase.jdbcx.SybDataSource objects. To use this factory, set the java.naming.object.factory system property to include com.sybase.jdbc3.SybObjectFactory.


Usage

You can use DataSource in different ways, in different applications. All options are presented in the following subsections with some code examples to guide you through the process. For more information, see the JDBC 2.0 Optional Package (formerly the JDBC 2.0 Standard Extension API), and the JNDI documentation on the Sun Web site.

1a. Configuration by administrator: LDAP

jConnect has supported LDAP connectivity since version 4.0. As a result, the recommended approach, which requires no custom software, is to configure DataSources as LDAP entries using the LDAP Data Interchange Format (LDIF). For example:

dn:servername:myASE, o=MyCompany, c=US
1.3.6.1.4.1.897.4.2.5:TCP#1# mymachine 4000
1.3.6.1.4.1.897.4.2.10:PACKETSIZE=1024&user=me&password=secret
1.3.6.1.4.1.897.4.2.11:userdb

1b. Access by client

This is the typical JDBC client application. The only difference is that you access the name server to obtain a reference to a DataSource object, instead of accessing the DriverManager and providing a JDBC URL. Once you obtain the connection, the client code is identical to any other JDBC client code. The code is very generic and references Sybase only when setting the object factory property, which can be set as part of the environment.

The jConnect installation contains the sample program sample2/SimpleDataSource.java to illustrate the use of DataSource. This sample is provided for reference only, that is, you cannot run the sample unless you configure your environment and edit the sample appropriately. SimpleDataSource.java contains the following critical code:

import javax.naming.*;
import javax.sql.*;
import java.sql.*;

// set necessary JNDI properties for your environment (same as above)
Properties jndiProps = new Properties();

// used by JNDI to build the SybDataSource
jndiProps.put(Context.OBJECT_FACTORIES,
    "com.sybase.jdbc3.jdbc.SybObjectFactory");

// nameserver that JNDI should talk to
jndiProps.put(Context.PROVIDER_URL,   "ldap:
//some_ldap_server:238/o=MyCompany,c=Us");

// used by JNDI to establish the naming context
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,
    "com.sun.jndi.ldap.LdapCtxFactory");

// obtain a connection to your name server
Context ctx = new InitialContext(jndiProps);
DataSource ds = (DataSource) ctx.lookup("servername=myASE");

// obtains a connection to the server as configured earlier.
// in this case, the default username and password will be used
Connection conn = ds.getConnection();

// do standard JDBC methods
...

Explicitly passing the Properties to the InitialContext constructor is not required if the properties have already been defined within the virtual machine, that is, passed when Java was either set as part of the browser properties, or by using the following:

java -Djava.naming.object.factory=com.sybase.jdbc3.jdbc.SybObjectFactory

See your Java VM documentation for more information about setting environment properties.

2a. Configuration by administrator: custom

This phase is typically done by the person who performs database system administration or application integration for their company. The purpose is to define a data source, then deploy it under a logical name to a name server. If the server needs to be reconfigured (for example, moved to another machine, port, and so on), then the administrator runs this configuration utility (outlined as follows) and reassigns the logical name to the new data source configuration. As a result, the client code does not change, since it knows only the logical name.

import javax.sql.*;
import com.sybase.jdbcx.*;
.....

// create a SybDataSource, and configure it
SybDataSource ds = new com.sybase.jdbc3.jdbc.SybDataSource();
ds.setUser("my_username");
ds.setPassword("my_password");
ds.setDatabaseName("my_favorite_db");
ds.setServerName("db_machine");
ds.setPortNumber(4000);
ds.setDescription("This DataSource represents the Adaptive Server
    Enterprise server running on db_machine at port 2638.  The default
    username and password have been set to 'me' and 'mine' respectively.  
    Upon connection, the user will access the my_favorite_db database on 
    this server.");
Properties props = newProperties()
props.put("REPEAT_READ","false");
props.put("REQUEST_HA_SESSION","true");
ds.setConnectionProperties(props);
// store the DataSource object. Typically this is
// done by setting JNDI properties specific to the
// type of JNDI service provider you are using.
// Then, initialize the context and bind the object.
Context ctx = new InitialContext();
ctx.bind("jcbc/myASE", ds);

Once you set up your DataSource, you decide where and how you want to store the information. To assist you, SybDataSource is both java.io.Serializable and javax.naming.Referenceable, but it is still up to the administrator to determine how the data is stored, depending on what service provider you are using for JNDI.

2b. Access by client

The client retrieves the DataSource object by setting its JNDI properties the same way the DataSource was deployed. The client needs to have an object factory available that can transform the object as it is stored (for example, serialized) into a Java object.

Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("jcbc/myASE");