How to Use JNDI Local Namespace in
WebSphere Studio V5,
With Sample Code

The Java Naming and Directory Interface (JNDI) is an important part of J2EE that specifies how to find an artifact by name (e.g., a database table) and how to use directory services, such as Lightweight Directory Access Protocol (LDAP). JNDI lets you create bindings that associate a name with an object. An important feature of JNDI is that a Java program can refer to an artifact, such as a database table, by a programmer-specified name and then use JNDI methods to resolve this internal name to the name (and location) of the actual object at runtime.

This sample program is the result from studying article http://www.e-promag.com/eparchive/dsp_printarticle.cfm?ContentID=4500 . I included my complete program and more detail configuration on the WebSphere.

Raw direct JDBC connection is the simplest way to connect to database. No any configuration is needed. I put the raw JDBC connection in the code. This will give user a more complete picture on how to connect to database.

The local namespace contains any name prefixed with

java:comp/env/

In our example, the database name is sample, the data source could be referred to as

java:comp/env/jdbc/sample

in a program, and the program could use JNDI methods to look up this name in the local namespace. WebSphere Application Server would then map the local name to a global name, which would then be mapped to an object.

Local namespaces provide an extra level of indirection, which makes it easier to assemble applications from components created by multiple providers. Local namespaces can eliminate naming conflicts among components and they also allow each component's resources to be configured in a consistent manner without having to know anything about the component's internal implementation. Using local namespaces also allows multiple versions of the same components to run independently in the same WebSphere Application Server cluster.

 

Start the Example

The sample will use DB2 from the EMPLOYEE table in the SAMPLE database.

Step 1. Create a project.

Since we do not want to use DefaultEAR, create a J2EE / Enterprise Application Project (project.gif ); JulieApp. Choose default J2EE 1.3 Enterprise Application project in next screen. Only check Web Project check box (module.gif) , enter name JulieProject. Then select JulieProject module, press finish to complete the project creation (app.gif).

Step 2. Write servlet code.

In WebSphere Studio Application Developer, switch to the Web perspective. Right click on JulieProject | JavaSource, select New | Servlet to create a servlet class JuliDataServlet. Use default to finish it. A file JuliDataServlet.java will be created and opened on the workplace.

The first step of a JNDI lookup is always to get an initial context:
Context aContext = new InitialContext();

By calling the constructor with no arguments, we get an initial context for the local namespace. Now the servlet looks up the data source using java:comp/env/jdbc/employee, which is a local name that I chose.
DataSource aDataSource = (DataSource) Context.lookup("java:comp/env/jdbc/employee");

The complete source code is:

----------------------
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.Servlet;
import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

/**
 * @version 	1.0
 * @author
 */
public class JuliDataServlet extends HttpServlet implements Servlet 
{

	public void doGet(HttpServletRequest req, HttpServletResponse resp)
		throws ServletException, IOException 
	{
		doPost( req,  resp);
	}
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
		throws ServletException, IOException 
	{
		Connection conn=null;
		PrintWriter out=resp.getWriter();
		try{
			//JNDI
			Context aContext = new InitialContext();
			DataSource aDataSource = (DataSource)aContext.lookup("java:comp/env/jdbc/employee");
			conn = aDataSource.getConnection();
			//JNDI end

			//raw JDBC for the same SAMPLEsample DB2 database 
			//Class.forName("COM.ibm.db2.jdbc.app.DB2Driver"); //need db2java.zip in the path 
			//conn = DriverManager.getConnection("jdbc:db2:sample");	//DB2
			//raw JDBC end

			String firstname="";
			String sql = "select firstnme, lastname from employee";
			Statement stm = conn.createStatement();
			ResultSet rst = stm.executeQuery(sql);
			for (int i=0; (i<10 && rst.next()); i++)		//only print 10 names
			{
				firstname =  rst.getString("firstnme");
				out.println("Hello "+ firstname+"," );
			}
			if(conn != null)
			{
				conn.close();
				System.out.println("Successfully closed");  
			}
		}
		catch (Exception e)
		{
			System.out.println(e);
		}
	
	}
}

----------------------

Step 3. Configure the server, and deployment

Now, we have to create a test server to run the sample application. Switch to the Server perspective. In the Server Configuration view, create a new "Server and Server Configuration" called JulietServer; it will be a WebSphere version 5.0 Test Environment. Accept the defaults.

Right click on JulieServlet (servlet.gif), pick Add and Remove Project. Select JulieApp and Add to the server. (servlet2.gif). Double click on JulieServlet to open Server Configuration view. Select the Data source tab, select "Default DB2 JDBC Provider," and click Add next to the table of Data sources. In the "Create a Data Source" dialog, select "DB2 JDBC Provider" and "Version 5.0", and click Next. In the Modify Data Source dialog (datasource.gif), Eenter EmployeeDataSource for the data source name and jdbc/employeedb for the JNDI name. This is comparable to an administrator defining a global name. Then click Next. accept the defaults (including SAMPLE as the database name) and click Finish. Save the server configuration and close the Server Configuration editor.

At deployment time, each component must define in its deployment descriptor all the resource names it expects to find in the local JNDI namespace: EJB homes, data sources, mail providers, Java Messaging Service queues and more. Data sources and other J2EE resources need to be defined by what are called resource references.

WebSphere Studio Application Developer makes this easy. In the Web perspective, expand the JulietProject and double-click the Web Deployment Descriptor (to open its editor), select the References tab at the bottom of this editor, and then select the Resource tab at the top. Click Add, define the name you are using (jdbc/employee), and specify javax.sql.DataSource as the type of object. Specify that the application will do the authentication. Now, as a developer, you happen to know that the deployer will use a different name, so specify jdbc/employeedb as the JNDI name for the WebSphere Binding for this resource. This is done so that your unit test will exercise the mapping of a local name to a global name. At this point, the editor looks like webxml.gif.

Step 4. Run the test.

Save the changes. Right click on JulieDataServlet.java, and select "Run on Server." run.gif shows the output displayed in the Web browser of WebSphere Studio Application Developer. We limited to 10 retured names.

When Bad Things Happen to Good Names

What if a name you expect to be there isn't there? How do you detect typos? Use the Universal Test Client. Open a Web browser (you can use the one in WebSphere Studio Application Developer or use your favorite) and type http://localhost:9080/UTC/ to bring it up. Click on JNDI Explorer, and expand the JDBC tree to see the names defined in the test environment.

After you deploy your application to WebSphere Application Server, there is a command line tool called DumpNameSpace. In Windows environments, it is located in C:\WebSphere\AppServer\bin by default.

 

JNDI Tutorial
http://java.sun.com/products/jndi/tutorial/index.html