Using JNDI in J2EE Applications

JNDI is a fundamental service to all J2EE applications. One key target is the isolation of the development of J2EE component code from the deployment environment. This allows an application component to be customized without the need to access or change its source code.

JNDI defines a logical namespace (directory) that application components (such as EJBs, servlets, JavaServer Pages [JSPs], and JDBC) can use to name resources, components, and other data. The namespace is provided to a component by its container, which executes the component. Typically, a component has a deployment descriptor that contains, among other data, information about the logical names and types of resources that the component references. Components of the Web tier are specified in the web.xml deployment descriptor, and those of the EJB tier are specified in the ejb-jar.xml deployment descriptor.

Starting with EJB 1.1, all beans have a default JNDI context called the enterprise naming context. The default context exists in the namespace called java:comp/env (based on a URL context for the java: URL scheme) and its subdirectories. When a bean is deployed, any beans it uses are mapped into the java:comp/env/ejb directory so that the bean references can be obtained at runtime through a simple and consistent use of the JNDI ENC. This eliminates network and implementation specific use of JNDI to obtain bean references. For example, you might use a name such as "java:comp/env/jdbc/myDB" from the initial context to name the myDB database. At the root context of the namespace is a binding with the name "comp", which is reserved for component-related bindings.

In addition, the name "env" is bound to a subtree that is reserved for the component's environment-related bindings, as defined by its deployment descriptor. The J2EE specifications recommend that EJBs be placed under the "ejb" subtree. For example, an EnrollmentCartHome EJB might be named "java:comp/env/ejb/EnrollmentCartHome".

Resource factory references are placed in subtrees differentiated by their resource manager type. Table 4.2 shows some examples.

Table 4.2. Resource Factory Subcontexts
SubcontextPurpose
jdbc:JDBC DataSource references
jms:JMS connection factories
mail:JavaMail connection factories
ejb:EJB component factories (home interface)

Typical J2EE application clients that use the JNDI are Java applications, applets, servlets, JSPs, TagLibs, and EJBs. Such clients locate services or components that are either local on the same JVM or remote and reside on a different host. Clients can be calling from the Web tier to the business-tier, or from the client tier to either the Web tier or to the EJB tier.

Three main types of J2EE objects can be maintained in JNDI:

  • Simple serializable JavaBeans (or Java objects)

  • Distributed object references, such as EJB home and remote interfaces

  • Common object services, such as transaction contexts

JNDI is used to declare a great deal of information to separate application code from its environment. The JNDI name that the application component uses to access the information is declared in the standard deployment descriptor. The following are the types of information that may be stored in the deployment descriptors by deployers and retrieved by developers using JNDI API:

  • Environment entries as declared by the env-entry elements

  • EJB references as declared by ejb-ref and ejb-local-ref elements

  • Resource manager connection factory references as declared by the resource-ref elements

  • Resource environment references as declared by the resource-env-ref elements

These XML elements of the deployment descriptors help you create portable applications across different environments. This is accomplished by specifying a logical name, to be used by the application, in the standard deployment descriptor. You then map this logical name to an environment-specific name. You specify this mapping in the server's specific deployment descriptor. Examples of this declarative concept will be illustrated in Day 9 and Day 16.

Each type of deployment descriptor element has a JNDI usage convention with regard to the name of the JNDI context under which the information is bound.

In addition to the standard deployment descriptors, there are deployment descriptors specific to each application server. For example, WebLogic Server uses weblogic-ejb-jar.xml, whereas JBoss uses jboss.xml as an additional EJB deployment descriptor that maps the JNDI name as used by each of the specific JNDI providers.

The following are sample codes to access some of the resources typically used in J2EE application. Details of these concepts will be covered in detail in the following days.

Looking Up EJB Components

The container is responsible for binding the home interfaces of its deployed enterprise beans available to the client through JNDI. A client locates a session bean's home interface using JNDI. For example, the remote home interface for the EnrollmentCart session bean can be located using the following code segment:

// Connect to JNDI service provider, and obtain ENC context
Context ctx = new InitialContext();

// Perform JNDI lookup to obtain EJB Home interface factory
EnrollmentCartHome enrollmentCartHome =
    (EnrollmentCartHome) ctx.lookup("java:comp/env/ejb/EnrollmentCartHome");

The deployment descriptor of the EJB is an XML file that specifies information (among other things) such as the JNDI names of the application's enterprise beans. The following is the <jndi-name> tag:

<jndi-name>ejb/EnrollmentCartHome</jndi-name>

The client begins by obtaining the InitialContext for a bean's home object. The InitialContext remains valid while the client session is valid. The client provides the JNDI registered name for the required object to obtain a reference to an administered object. In the context of an EJB application, a typical administered object is an enterprise bean's home object. You'll see more detail coverage of JNDI access to EJB in Days 6, 8, 10, and 11.

Looking Up JMS Factory and Destination

A client can locate the JMS Destination (Queue or Topic) to which it should send messages (that are to be delivered to a message-driven bean) by means of the standard JNDI API:

// Connect to JNDI service provider, and obtain ENC context
Context ctx = new InitialContext();
// Perform JNDI lookup to obtain queue connection factory
QueueConnectionFactory qcf = (QueueConnectionFactory)
       ctx.lookup("java:comp/env/jms/QueueCF");
// Perform JNDI lookup to obtain queue name
Queue  q = (Queue) ctx.lookup("java:comp/env/jms/StudentQueue");

For JMS applications, the administered object can be a JMS ConnectionFactory (for a Topic or a Queue) or a JMS Destination (a Topic or a Queue). A detailed explanation of these concepts is provided in Day 13, “Understanding JMS and Message-Driven Beans.”

Looking Up JDBC Connection Pool

Administrators or deployers of J2EE application can specify external resources such as JDBC pools. A resource file, such as a deployment descriptor, is used for this purpose:

// Connect to JNDI service provider, and obtain ENC context
Context ctx = new InitialContext();
// Perform JNDI lookup to obtain JDBC connection pool factory
DataSource ds = (DataSource) ctx.lookup ("java:/comp/env/jdbc/myDBPool");

The following is the associated deployment descriptor to specify the resource:

<resource-ref>
        <res-ref-name>jdbc/myDBPool</res-ref-name>
        <res-type>java.sql.DataSource</res-type>
</resource-ref>

More detailed coverage of JDBC can be found in Day 9, “Using JDBC to Connect to a Database.”

Looking Up JTA User Transaction

The JTA interface is used in distributed transactions to demarcate transaction boundaries within EJB applications. Clients use it to look up the UserTransaction as a resource factory:

// Connect to JNDI service provider, and obtain ENC context
Context ctx = new InitialContext();
// Perform JNDI lookup to obtain User Transaction resource factory
UserTransaction tx = (UserTransaction) ctx.lookup(
         "java:comp/UserTransaction");
tx.begin();
//...perform the distributed transaction...
tx.commit();

More detailed coverage of JTA can be found in Day 18, “Building Bean-Managed Transaction Beans.”

Looking Up JavaMail Session

The JavaMail interface is important in J2EE applications for sending mail from inside EJBs or other components. Clients use it to obtain a Session object in order to send email messages to the mail server:

// Connect to JNDI service provider, and obtain ENC context
InitialContext ctx = new InitialContext();
// Perform JNDI lookup to obtain Mail Session resource factory
Session session = (Session) ctx.lookup("java:comp/env/mail/MailSession");

More detailed coverage of JavaMail can be found in Day 20, “Putting It All Together.”

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.247.53