Section 4.3. JNDI


4.3. JNDI

Let's take a moment to parse the DataSource name java:comp/env/jdbc/JBossAtWorkDS, which is a Java Naming and Directory Interface (JNDI) name. JNDI provides access to a variety of back-end resources in a unified way.

JNDI is to Java Enterprise applications what Domain Name Service (DNS) is to Internet applications. Without DNS, you would be forced to memorize and type IP addresses like 192.168.1.100 into your web browser instead of friendly names like http://www.jbossatwork.com. In addition to resolving host names to IP addresses, DNS facilitates sending email between domains, load-balancing web servers, and other things. Similarly, JNDI maps high-level names to resources like database connections, JavaMail sessions, and pools of EJB objects.

DNS has a naming convention that makes it easy to figure out the organizational structure of a Fully Qualified Domain Name (FQDN). Domain names are dot-delimited and move from the general to the specific as you read them from right-to-left. "com" is a Top-Level Domain (TLD) reserved for commercial businesses. There are a number of other TLDs, including "edu" for educational institutions, "gov" for government entities, and "org" for non-profit organizations.

The domain name reserved for your business or organization is called a Mid-Level Domain (MLD). Jbossatwork.com, apache.org, and whitehouse.gov are all MLDs. You can create any number of subdomains under a MLD, but the left-most element will always be a HostName like "www" or "mail."

Now looking at a domain name like http://www.parks.state.co.us or http://www.npgc.state.ne.us for a listing of state parks in Colorado or Nebraska begins to make a little more sense. The country/state/department hierarchy in the domain name mirrors the real-life organizational hierarchy.

JNDI organizes its namespace using a naming convention called Environmental Naming Context (ENC). You are not required to use this naming convention, but it is highly recommended. ENC JNDI names always begin with java:comp/env. (Notice that JNDI names are forward slash-delimited instead of dot-delimited and read left-to-right.)

A number of TLD-like top-level names are in the ENC. Each JNDI "TLD" corresponds to a specific resource type, shown in Table 4-1.

Table 4-1. J2EE-style JNDI ENC naming conventions

Resource type

JNDI prefix

Environment Variables

java:comp/env/var

URL

java:comp/env/url

JavaMail Sessions

java:comp/env/mail

JMS Connection Factories and Destinations

java:comp/env/jms

EJB Homes

java:comp/env/ejb

JDBC DataSources

java:comp/env/jdbc


I'm obviously mixing my JNDI and DNS nomenclature, but the JNDI "TLD" for DataSources always should be java:/comp/env/jdbc. In the example DataSource namejava:comp/env/jdbc/JBossAtWorkDSthe "TLD" and "MLD" should be more self-evident now. JBossAtWorkDS is the JNDI "MLD."

DNS names protect us from the perils of hardcoded IP addresses. A change of server or ISP (and the corresponding change in IP address) should remain transparent to the casual end user since their handle to your site is unchanged. Similarly, JNDI gives J2EE components a handle to back-end resources. Since the component uses an alias instead of an actual value (for the database driver, for example) we now have the flexibility to swap out back-end resources without changing the source code.

These JNDI names are local to the EAR. If you deploy multiple EARs to the same JBoss instance, each EAR will get its own JNDI local context. This ensures that your JNDI names are available only to the EAR in which they are set.

In the spirit of encapsulation, we wrap all of the JNDI lookups in class called ServiceLocator. It allows us to constrain all of the JNDI semantics to a single class. Here's what our ServiceLocator class looks like in Example 4-3.

Example 4-3. ServiceLocator.java
 package com.jbossatwork.util; import javax.naming.*; import javax.sql.*; public class ServiceLocator {     private ServiceLocator(  ) {  }     public static DataSource getDataSource(String dataSourceJndiName)                   throws ServiceLocatorException {         DataSource dataSource = null;         try {             Context ctx = new InitialContext(  );             dataSource = (DataSource) ctx.lookup(dataSourceJndiName);         } catch (ClassCastException cce) {             throw new ServiceLocatorException(cce);         } catch (NamingException ne) {             throw new ServiceLocatorException(ne);         }         return dataSource;     } } 

All JNDI variables are stored in the InitialContext. When you call the lookup( ) method, it returns an Object that must be cast to the appropriate type. If you think about it, this is really no different than calling HashMap.get("JBossAtWorkDS").

Now we can see how to get a DataSource by doing a JNDI lookup. But this probably brings up the next obvious question: how did our DataSource get into the InitialContext in the first place? To find out, we need to revisit your favorite deployment descriptor, web.xml.



JBoss at Work. A Practical Guide
JBoss at Work: A Practical Guide
ISBN: 0596007345
EAN: 2147483647
Year: 2004
Pages: 197

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net