Implementing and Deploying a Session Bean


For a comprehensive introduction to EJBs, I highly recommend Richard Monson-Haefel’s book [1]. This sidebar describes the overall process for implementing and deploying a stateless session bean that exposes a remote interface to its clients.

You may download the example application and its source code from <www.cuj.com/java/code.htm>. In order to use the example, you will need a J2EE application server that implements the EJB Specification v2.0 [2]. I used the J2EE v1.3.1 reference implementation freely available from Sun Microsystems. To compile the application’s source code, I employed Ant v1.4.1 from the Apache Software Foundation’s Jakarta Project and the JDK v1.3.1_03 from Sun Microsystems.

Session Beans are frequently used to implement workflow within an application. They come in two flavors: stateful and stateless. The distinction is simple. From a client object’s perspective, a stateful session bean maintains a consistent state across the set of method calls the client makes to it. A stateless session bean does not guarantee this conversational consistency. As a result, stateless session beans are lightweight and cheap to employ (in terms of both relative resource consumption and performance).

Imagine an application in which a stateless session bean called StaticLiaisonBean enlists a second stateless session bean called UpperCaseConverterBean to perform some unit of work. StaticLiaisonBean exposes a method called forward to its clients that accepts a character string and returns the string in a modified form. In order to modify this string, StaticLiaisonBean calls UpperCaseConverterBean’s exposed process method. This method also accepts a character string and returns one. As you can guess, this bean merely converts the given string to all uppercase. To create this application, I performed three activities: bean development, component and application assembly, and application deployment. I also wrote a trivial client to exercise the application.

To create a session bean, I must write the implementing class as well as a home interface and a proxy interface. These two interfaces allow client objects to acquire and interact with the bean. (The deployment tools associated with a specific application server take these two interfaces and automatically generate implementing classes.)

For a session bean such as StaticLiaisonBean, the implementing class (Listing 1) must implement the interface javax.ejb.SessionBean. This interface contains the callback methods that the application server will use to manage this bean. Since this interface includes a number of methods that are superfluous to a stateless session bean, I have employed an adaptor class [3] (Listing 2) to minimize clutter in the bean’s class. In fact, the only callback needed in this example is ejbCreate, which is analogous to a constructor in the conventional Java world. In ejbCreate, the bean acquires a reference to its assistant, UpperCaseConverterBean. I will discuss this acquisition process in more detail in the main article. The bean class must also define the forward business method it exposes to its clients. In this case, the method just displays evidence that it was invoked and passes the given string on to its assisting bean.

The proxy interface (Listing 3) contains the set of business methods that a bean exposes to its clients. In this application, the proxy interface for both beans extends the javax.ejb.EJBObject interface. The home interface (Listing 4) contains the set of bean lifecycle methods that clients may use to acquire and release instances of a bean. In this application, the home interface exposes a simple create method that accepts no arguments and returns a reference to the bean’s proxy interface.

Once the class and interface files compile, I turn to component and application assembly. A component is simply a set of beans and their associated supporting classes. Each component is deployed in its own jar file. After I marshal each bean into its component jar file, I write the component’s deployment descriptor. Once the components are assembled, I marshal their jar files into the application ear file and write the application deployment descriptor.

Component deployment descriptors (Listing 5) contain metadata for each bean in the component. Bean metadata includes the bean’s name and class, values for its environment variables (env-entry stanzas), and a list of every enterprise bean with which it may interact (ejb-ref stanzas). The application metadata (unique to each application server) captured in its deployment descriptor (Listing 6) includes the set of JNDI (Java Naming and Directory Interface) namespace entries (jndi-name stanzas) that need to be bound to the application server’s namespace upon deployment of the application. In EJB 2.0, a deployment descriptor is a series of nested XML stanzas stored in a file. The DTD (document type definition) that defines a valid deployment descriptor is in the EJB Specification.

The J2EE reference implementation has a helpful GUI deployment tool that makes component and application assembly a fairly straightforward process. If you have it available, you may open this application’s ear file and view all of the metadata. Otherwise, you may employ the jar utility to unpack the ear file and its contained jar files to view the metadata in XML form.

Application deployment is an automated process in which the vendor’s deployment tool generates a class that implements the remote interface and another that implements the remote home interface for each bean. The deployment tool also generates a set of helper classes to complete each bean’s integration with the target application server. Finally, the deployment tool packages all of these new files into the appropriate component jar file and then adds application-server-specific deployment descriptors to the application’s ear file.