ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Developing Your First EJBs, Part 2
Pages: 1, 2

The TravelAgent EJB's Deployment Descriptor

The TravelAgent EJB uses an XML deployment descriptor similar to the one used for the Cabin entity bean. The following sections contain the ejb-jar.xmlfile used to deploy the TravelAgent bean in EJB. Chapter 11 describes how to deploy several beans in one deployment descriptor, but for now the TravelAgent and Cabin EJBs are deployed separately.

EJB 2.1: Deployment descriptor

In EJB 2.1, the deployment descriptor for the TravelAgent EJB looks like this:



<?xml version="1.0" encoding="UTF-8" ?>
<ejb-jar 
     xmlns="http://java.sun.com/xml/ns/j2ee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                         http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
     version="2.1">
    <enterprise-beans>
        <session>
            <ejb-name>TravelAgentEJB</ejb-name>
            <home>com.titan.travelagent.TravelAgentHomeRemote</home>
            <remote>com.titan.travelagent.TravelAgentRemote</remote>
            <ejb-class>com.titan.travelagent.TravelAgentBean</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Container</transaction-type>
            <ejb-ref>
                <ejb-ref-name>ejb/CabinHomeRemote</ejb-ref-name>
                <ejb-ref-type>Entity</ejb-ref-type>
                <home>com.titan.cabin.CabinHomeRemote</home>
                <remote>com.titan.cabin.CabinRemote</remote>
            </ejb-ref>
            <security-identity><use-caller-identity/></security-identity>
        </session>
    </enterprise-beans>
    <assembly-descriptor>
    ...
    </assembly-descriptor>
</ejb-jar>

EJB 2.0: Deployment descriptor

In EJB 2.0, the deployment descriptor for the TravelAgent EJB looks like this:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
    <enterprise-beans>
        <session>
            <ejb-name>TravelAgentEJB</ejb-name>
            <home>com.titan.travelagent.TravelAgentHomeRemote</home>
            <remote>com.titan.travelagent.TravelAgentRemote</remote>
            <ejb-class>com.titan.travelagent.TravelAgentBean</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Container</transaction-type>
            <ejb-ref>
                <ejb-ref-name>ejb/CabinHomeRemote</ejb-ref-name>
                <ejb-ref-type>Entity</ejb-ref-type>
                <home>com.titan.cabin.CabinHomeRemote</home>
                <remote>com.titan.cabin.CabinRemote</remote>
            </ejb-ref>
            <security-identity><use-caller-identity/></security-identity>
        </session>
    </enterprise-beans>
    <assembly-descriptor>
    ...
    </assembly-descriptor>
</ejb-jar>

EJB 2.0 and 1.1: Defining the XML elements

The only significant difference between the 2.1 and 2.0 deployment descriptors is that EJB 2.1 declares the use of an XML Schema for validation while EJB 2.0 uses a DTD.

Other than the <session-type> and <ejb-ref> elements, the TravelAgent EJB's XML deployment descriptor should be familiar: it uses many of the same elements as the Cabin EJB's. The <session-type> element can be Stateful or Stateless, to indicate which type of session bean is used. In this case, we are defining a stateless session bean.

The <ejb-ref> element is used at deployment time to map the bean references used within the TravelAgent EJB. In this case, the <ejb-ref> element describes the Cabin EJB, which we already deployed. The <ejb-ref-name> element specifies the name that must be used by the TravelAgent EJB to obtain a reference to the Cabin EJB's home. The <ejb-ref-type> tells the container what kind of bean it is, Entity or Session. The <home> and <remote> elements specify the fully qualified interface names of the Cabin's home and remote bean interfaces.

When the bean is deployed, the <ejb-ref> will be mapped to the Cabin EJB in the EJB server. This is a vendor-specific process, but the outcome should always be the same. When the TravelAgent EJB does a JNDI lookup using the context name "java:comp/env/ejb/CabinHomeRemote", it obtains a remote reference to the Cabin EJB's home. The purpose of the <ejb-ref> element is to eliminate network-specific and implementation-specific use of JNDI to obtain remote bean references. This makes a bean more portable, because the network location and JNDI service provider can change without affecting the bean code or even the XML deployment descriptor.

While we haven't yet created a local interface for our beans, it's always preferable to use local references instead of remote references when beans access each other within the same server. Local references are specified using the <ejb-local-ref> element, which looks just like the <ejb-ref> element.

The <assembly-descriptor> section of the deployment descriptor is the same for EJB 2.1 and EJB 2.0:

<assembly-descriptor>
    <security-role>
        <description>
            This role represents everyone who is allowed full access 
            to the TravelAgent EJB.
        </description>
        <role-name>everyone</role-name>
    </security-role>

    <method-permission>
        <role-name>everyone</role-name>
        <method>
            <ejb-name>TravelAgentEJB</ejb-name>
            <method-name>*</method-name>
        </method>
    </method-permission>

    <container-transaction>
        <method>
            <ejb-name>TravelAgentEJB</ejb-name>
            <method-name>*</method-name>
        </method>
        <trans-attribute>Required</trans-attribute>
    </container-transaction>
</assembly-descriptor>

Deploying the TravelAgent EJB

Once you've defined the XML deployment descriptor, you are ready to place the TravelAgent EJB in its own JAR file and deploy it into the EJB server. Use the same process to JAR the TravelAgent EJB as you used for the Cabin EJB. Shrink-wrap the TravelAgent EJB class and its deployment descriptor into a JAR file and save the file to the com/titan/travelagent directory:

\dev % jar cf travelagent.jar com/titan/travelagent/*.class META-INF/ejb-jar.xml

F:\..\dev>jar cf travelagent.jar com\titan\travelagent\*.class META-INF\ejb-jar.xml

You might have to create the META-INF directory first, and copy ejb-jar.xml into that directory. The TravelAgent EJB is now complete and ready to be deployed.

To make your TravelAgent EJB available to a client application, you need to use the deployment utility or wizard of your EJB server. The deployment utility reads the JAR file to add the TravelAgent EJB to the EJB server environment. Unless your EJB server has special requirements, it is unlikely that you will need to change or add any new attributes to the bean. You will not need to create a database table, since the TravelAgent EJB is using the Cabin EJB and is not itself persistent. However, you will need to map the <ejb-ref> element in the TravelAgent EJB's deployment descriptor to the Cabin EJB. Your EJB server's deployment facilities provides a mechanism for accomplishing this task (see Exercise 4.2 in the Workbook).

Creating a Client Application

To show that our session bean works, we'll create a simple client application that uses it. This client produces a list of cabins assigned to ship 1 with a bed count of 3. Its logic is similar to the client we created earlier to test the Cabin EJB: it creates a context for looking up TravelAgentHomeRemote, creates a TravelAgent EJB, and invokes listCabins( ) to generate a list of the cabins available. Here's the code:

import com.titan.travelagent.TravelAgentRemote;
import com.titan.travelagent.TravelAgentHomeRemote;

import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.ejb.CreateException;
import java.rmi.RemoteException;
import java.util.Properties;
import javax.rmi.PortableRemoteObject;

public class Client_3 {
    public static int SHIP_ID = 1;
    public static int BED_COUNT = 3;

    public static void main(String [] args) {
        try {
            Context jndiContext = getInitialContext( );
           
            Object ref = jndiContext.lookup("TravelAgentHomeRemote");
            TravelAgentHomeRemote home = (TravelAgentHomeRemote)
                PortableRemoteObject.narrow(ref,TravelAgentHomeRemote.class);
        
            TravelAgentRemote travelAgent = home.create( );
        
            // Get a list of all cabins on ship 1 with a bed count of 3.
            String list [] = travelAgent.listCabins(SHIP_ID,BED_COUNT);
        
            for(int i = 0; i < list.length; i++){
                System.out.println(list[i]);
            }
        
        } catch(java.rmi.RemoteException re){re.printStackTrace( );}
            catch(Throwable t){t.printStackTrace( );}
    }
    static public Context getInitialContext( ) throws Exception {
        Properties p = new Properties( );
        // ... Specify the JNDI properties specific to the vendor.
        return new InitialContext(p);
    }
}

When you have successfully run Client_3, the output should look like this:

1,Master Suite                  ,1
3,Suite 101                     ,1
5,Suite 103                     ,1
7,Suite 105                     ,1
9,Suite 107                     ,1
12,Suite 201                     ,2
14,Suite 203                     ,2
16,Suite 205                     ,2
18,Suite 207                     ,2
20,Suite 209                     ,2
22,Suite 301                     ,3
24,Suite 303                     ,3
26,Suite 305                     ,3
28,Suite 307                     ,3
30,Suite 309                     ,3

You have now successfully created the first piece of the TravelAgent session bean - a method that obtains a list of cabins by manipulating the Cabin EJB entity.


Return to ONJava.com.