New York University

Computer Science Department

Courant Institute of Mathematical Sciences

 

Session 11: Deploying an EJB Application

 

Course Title: Extreme Java                                                                 Course Number: g22.3033-007

Instructor: Jean-Claude Franchitti                                                         Session: 11

 

 

 

 

I. Building an Deploying an EJB Application

 

An Enterprise JavaBean (EJB) is a server-based Java component that you build and deploy according to Sun's Enterprise JavaBean specification. To deploy applications that include EJB components, you must install a server that offers EJB support in compliance with the specification. Such a server must provide an EJB container mechanism. Many application-server products, including BEA Weblogic, IBM WebSphere, Persistence PowerTier, and Novera jBusiness4, have added EJB container support. The example described in this section was deployed successfully on BEA Weblogic 5.1 using Inprise's Jbuilder 2, and on BEA Weblogic 4.5.1 using VisualCafe Enterprise Suite 3.1 or VisualAge for Java Integration Kit version 2.0.software.

 

EJB offers an extremely promising mechanism to develop and deploy distributed business components. However, when you take a hard look at the EJB component model and how it was being supported in the software community, you can find a number of contradictions. On the one hand, EJB promises a consistent development model and a high degree of portability. On the other, evolution of the EJB specification has been slow. Some key vendors have taken a wait-and-see attitude, while others have implemented EJB support in a manner that binds developers to their application server products. Both the slow introduction of development tools with strong support for EJBs and developer confusion over how EJB fits into the Java API alphabet soup have delayed adoption of this technology. Against that backdrop, developers have stuck with other server-side Java deployment techniques that include developing components with custom interfaces and using servlets.

 

This homework describes the taxonomy of EJB by developing a fairly simple application that uses an EJB component. While the name EJB implies a single granular component, developing applications that use EJBs requires that you construct several classes and interfaces for each EJB that you want to deploy, as well as additional material that articulates its runtime characteristics to your EJB server. Further complicating any discussion of EJB is the fact that there are two principal types of EJBs -- session beans and entity beans -- which have slightly different characteristics and modes of operation. Session beans themselves can operate as stateful or stateless components; in the former case, they maintain state variables that a client can access across method calls.

 

The proposed EJB example application lets a Web-site builder add an "instant poll" to a site. Many sites, like CNN's, have a daily poll in which visitors can register their opinions on a topic of interest. We'll develop an EJB that supports a client form in which a user browsing the site can read the poll question and click on a radio button that represents one of two responses. The client form will initially be developed as an applet, but subsequent versions could be offered in HTML form and invoked from a servlet, or from Java Server Pages (JSP). The homework uses a small database with two tables. One table contains poll questions and two choices of responses, with start and end dates and a counter for the cumulative number of votes. Each response is recorded in a second table. Thus there can be multiple active polls at any time; when a visitor arrives on the page, the EJB will return a list of active questions in a vector. After the visitor casts his or her vote, the EJB will tally the response and store the cumulative result.

 

Developing the aforementioned application using EJBs requires coding the bean itself, along with a home interface and one or more remote interfaces. Then a deployment package must be built, and the EJB server must be configured to load the EJB when it starts. Establishing the relationship between the bean and the interfaces relies on a little bit of "magic" that the EJB server performs at startup. To start with, an EJB skeleton is created using the EJB wizard in Inprise JBuilder 2. The generated skeleton looks as illustrated in Example 1 below.

.

 


 


Example 1: Creating an EJB skeleton with JBuilder 2's EJB wizard.

 

The code in Example 1 illustrates the basic structure of any session bean; entity beans look similar, although they implement the EntityBean class. Every EJB declares a context object that the container will use as a handle for communicating with the bean. It's a SessionContext object for a session bean, or an EntityContext object for an entity bean. Every EJB must also include the ejbCreate(), ejbActivate(), ejbPassivate(), and ejbRemove() methods. The EJB container performs the creation, activation, passivation, and removal of bean instances automatically; it is necessary to provide code to implement these methods only when you need to perform very specialized tasks. A session bean may have multiple ejbCreate() methods with different signatures, where a signature describes the parameters required to call the method. The container calls the setSessionContext method to associate a bean instance with the context that it maintains for that instance.

 

Entity beans replace the setSessionContext method with a setEntity Context method and an unsetEntityContext method, which lets the container disassociate the bean instance from persistent resources prior to terminating it. Additionally, the entity-bean interface includes ejbLoad() and ejbStore() methods. An entity bean can manage persistence, or it can let the container handle persistence on its behalf. If the bean manages persistence, the developer needs to add code to load an instance of the entity in ejbLoad() and to store it in ejbStore().

 

Of course, you must also define and write code for the methods that implement your custom application logic, in addition to the methods defined by the EJB object interfaces. The proposed application implements the following methods:

 

ˇ        getQuestions() makes a JDBC connection to the Polls table and retrieves the active polls. It then packages the active polls into a vector of strings. Each element in the vector describes a poll. getQuestions() returns this vector.

 

ˇ        recordAnswer(ID, Answer) is a simple method that makes a JDBC connection to the polls database and inserts a new record into the PollResults table with the ID of the Poll that the client responded to, and an integer representing the response.

 

 

Once the code for the EJB component itself is complete, the home and remote interfaces need to be defined. The client must call the create method defined in the home interface to request that the container provide it with a bean instance. This create method corresponds to the ejbCreate method in the session bean. The parameter sets of the two methods are identical. When the client calls PollHome.create(), the container allocates an instance of the EJB and calls the bean's own ejbCreate() method. The remote interface declares the bean's public methods; the client will import this interface definition so that it can resolve those method names, and the session bean itself will implement the methods as illustrated in Example 2 below.

 

 

 



 

 

 

 

 

 

 


 

 


Example 2: Methods implemented by the session bean.

 

 


Once the bean and the required interfaces are coded, a suitable container must be prepared to deploy the bean. The first part of this homework will use the Weblogic application server, which includes EJB support among a number of other features. The first step is to write a deployment descriptor, which is a text file that declares execution-time characteristics of the application, including those in Example 3 below.

 

 


Example 3: A deployment descriptor containing declarations

of execution-time characteristics.

 

 

The simple deployment descriptor above tells the server where to find the server class and the interfaces, and specifies that the proposed bean requires the creation of a transaction if one is not already in process when the bean starts to work. The descriptor also specify how many beans the server should allow to reside on the server at any one time. After finishing the deployment descriptor, a manifest needs to be created. A manifest is a very simple file that tells the EJB server where to look for the deployment descriptor.

 

The next step after creating all of these pieces is to build the classes that the server will execute as part of the EJB application. The first part of the process consists of serializing the deployment-descriptor text file. The EJB files that implement the bean and define its interfaces must then be compiled. After compiling the EJB code, the JAR tool is used to create a Java archive file for deployment.

 

The final step generates the class files that contain the bean's public interface. An EJB container doesn't permit methods on the EJB remote interface to call the bean directly, so the container itself must generate the publicly accessible classes. The Weblogic EJB compiler generates these wrapper classes using, as a command line parameter, the name of the JAR file that needs wrapper classes.

 

Other containers may use different mechanisms to perform this step. Note that the entire process of developing and deploying EJB is fraught with details that have to be specified correctly, or else the server will respond with a cryptic error message. This process includes coding the database table creation scripts, creating the deployment descriptor and the manifest, generating the implementation classes, making correct entries in the Weblogic properties file, and specifying classpath settings that match the directory structures and the parameters in the build files. Each of these steps are an opportunity to trip users of EJB-based application servers; while examples help, there is a definite need for more wizard-like utilities that automate part of the process.

 

Finally, the bean is deployed by adding an entry to the application server's property file. This entry points to the serialized deployment-descriptor file, and tells the server to load the bean at startup, using the parameters specified in that file.

 

Calling the Bean

The keys to writing a client that can use the proposed EJB lie in the classes the client imports: the Java Naming and Directory Interface (JNDI) classes, and the home and remote interfaces that were defined. When the applet starts, it initializes a context object and then makes a JNDI call to locate the home interface for the PollMgr object. The container processes this request; as it does, it creates an instance of the home interface, associates a context with it, and returns the home interface instance handle to the client. The client must then call the PollHome.create() method on the home interface to request that the container create an instance of our bean on the server. The code for these steps is illustrated in Example 4 below.

 


 


Example 4: Using the Create() method to create an instance of a bean on the server.

 

Now that the EJB container has been notified that a client would like to use services provided by the PollMgr session bean, the methods defined on the remote interface can be called as illustrated in Example 5 below.

 


Example 5: Calling the methods defined on the remote interface.

 


The getQuestions method will return a vector in which each element contains the Poll ID, the question, and both an affirmative and a negative response string (for example, "1", "Should Mike Tyson be allowed to fight again", "I'd love to see him fight", "No, they should lock him up and throw away the key"). getQuestions may return several questions, allowing creation of a client that offers the visitor an opportunity to vote on a number of issues without returning to the server. The client calls recordAnswer, supplying the ID of the poll that the response pertains to and the selected alternative as parameters.

 

The Portability Promise

 

Java promises that applications can be written once and run everywhere. Having just completed developing a simple EJB application, the question is: How well does the Java community fulfill that promise across different application servers?

 

EJB technology clearly goes a long way towards establishing a server-side component architecture that much of the software industry supports. EJB standardizes the infrastructure and establishes a model whereby the developer of the component runtime environment, or EJB server, is responsible for handling remote invocation, transaction processing, security, threading, and state management. Application developers no longer need to concern themselves with any of these plumbing issues. The EJB specification defines which services the component runtime environment must provide and permits specialized containers to provide additional services beyond those that it defines. Of course, an EJB that depends on such a service can be deployed only in a container that supports that service.

 

II. Building an Deploying an EJB Application with WebSphere

 

IBM's WebSphere application server product provides a middle tier execution platform for Java and XML based services. Websphere is built around a server side Java runtime engine, optimized for running servlets and Java Server Pages. The Advanced edition adds CORBA and Enterprise JavaBean (EJB) support, which is obviously the focus of this lab. Being an IBM product, WebSphere runs on a broad array of computer/OS platforms including Intel/NT, Intel/Linux, Sun Solaris, AIX, OS/2, AS/400, and OS/390. For the purpose of this handout, we will show how install and configure the EJB applications, deployed earlier on WebLogic, on WebSphere 3.02 using WebSphere Studio for Windows NT workstation, running Microsoft's IIS or personal web server.

 

Deploying EJBs on WebSphere is a three-step process. First, the necessary classes must be written and compiled. Second, an EJB Jar file must be prepared using a tool called Jet that WebSphere provides. Third, the WebSphere administration application must be used to deploy the EJBs into the server.

 

Writing the class files is relatively easy; the polling application bean developed in the first part of lab 7 is readily usable. No changes to the EJB code are required. Changes can be made to the client, to take advantage of classes (e.g. com.ibm.ejb.client.util.EJBHelper) that IBM provides to support JNDI lookups of EJB Home interfaces.

 

Once the code is reviewed, the classes should be compiled and the Jar utility should be used to create a standard Jar file containing the remote interface class file, the home interface class file, and the session bean class files. IBM's Jet tool should then be used to create an EJB Jar file (i.e. a Jar file that includes a serialized EJB deployment descriptor as specified in Sun's EJB specification). The Jet tool automates the job of specifying the EJB's runtime properties and creating a deployment descriptor that the Application Server can read to establish those properties at runtime. The Jet tool provides both a GUI interface and a command line mode, in which it reads the property values from an XML file that describes deployment properties in accordance with the syntax defined in the supplied  JetDTD.dtd document type definition.

 

IBM is adopting XML as a mechanism for meta data definitions throughout their product lines. The jetDTD.dtd is a document type definition file that define the components of an EJB deployment descriptor in terms of XML elements and attributes. Listing 1 below illustrates the  content of the jetDTD.dtd file.

 

 

Listing 1: The jetDTD.dtd file.

 

<?xml encoding="US-ASCII"?>

<!ELEMENT ejb-jars (ejb-jar)*>

<!ELEMENT ejb-jar

    (input-file                 |

     output-file                |

     entity-bean                |

     session-bean               |

     JNDI-name                  |

     transaction-attribute      |

     isolation-level            |

     run-as-mode                |

     enterprise-bean-class      |

     remote-interface-class     |

     home-interface-class       |

     method                     |

     dependency                 |

     environment                |

     ace-identity)*>

<!ELEMENT input-file (#PCDATA)>

<!ELEMENT output-file (#PCDATA)>

<!ELEMENT entity-bean

    (primary-key-class  |

     re-entrant |

     container-managed-field)*>

<!ELEMENT primary-key-class (#PCDATA)>

<!ELEMENT re-entrant EMPTY>

<!ATTLIST re-entrant

    value (true | false | TRUE | FALSE | True | False) #REQUIRED>

<!ELEMENT container-managed-field (#PCDATA)>

<!ELEMENT session-bean

    (session-timeout    |

     state-management-attribute)*>

<!ELEMENT JNDI-name (#PCDATA)>

<!ELEMENT session-timeout (#PCDATA)>

<!ELEMENT state-management-attribute EMPTY>

<!ATTLIST state-management-attribute

    value (STATELESS | STATEFUL) #REQUIRED>

<!ELEMENT transaction-attribute EMPTY>

<!ATTLIST transaction-attribute

    value (TX_NOT_SUPPORTED     |

           TX_BEAN_MANAGED      |

           TX_REQUIRED          |

           TX_REQUIRES_NEW      |

           TX_MANDATORY         |

           TX_SUPPORTS) #REQUIRED>

<!ELEMENT isolation-level EMPTY>

<!ATTLIST isolation-level

    value (READ_UNCOMMITTED     |

           READ_COMMITTED       |

           REPEATABLE_READ      |

           SERIALIZABLE) #REQUIRED>

<!ELEMENT run-as-mode (#PCDATA)*>

<!ATTLIST run-as-mode

    value (CLIENT_IDENTITY      |

           SPECIFIED_IDENTITY   |

           SYSTEM_IDENTITY) #REQUIRED>

<!ELEMENT enterprise-bean-class (#PCDATA)>

<!ELEMENT remote-interface-class (#PCDATA)>

<!ELEMENT home-interface-class (#PCDATA)>

<!ELEMENT method

    (name               |

     isolation-level    |

     run-as-mode        |

     ace-identity       |

     transaction-attribute)*>

<!ELEMENT name (#PCDATA)>

<!ELEMENT environment (#PCDATA)>

<!ELEMENT dependency

    (class      |

     on)*>

<!ELEMENT class (#PCDATA)>

<!ELEMENT on (#PCDATA)>

<!ELEMENT ace-identity  (#PCDATA)>

 

 

The Jet tool should be run interactively. Upon building an EJB-Jar file, the tool creates an XML version of the settings so that it is possible to run the tool from the command line in order to  rebuild the EJB-Jar file later as needed. The Jet tool does the bulk of its data collection on the SessionBean and EntityBean descriptor tabs. It allows to set values for Session Timeout in seconds, the session bean State Management attribute, the Transaction Attribute and Isolation level, and the security characteristics. For entity beans, it is necessary to specify which instance variables the container should save to the data store. On the methods tab, the Jet tool lists all of the methods declared in the EJB and allows overriding of the bean's default transaction attribute, Isolation Level, Run-As Mode, and Identity for each method. Figure 1 below shows the Jet tool user interface.

 

IBM's Jet tool presents a tabbed dialog that allows specification of properties for Entity Beans, Session Beans, specific Method overrides, Environment settings and dependencies. The Session Bean property page allows entry of values for descriptor fields such as session timeout value, state management attribute, JNDI home name, and transaction management parameters.

 

 


 


Figure 1: The Jet Tool User Interface

 

The environment tab allows the edition of any environmental settings that may be required, or the import of environmental settings from a file. The dependencies tab lists interclass dependencies that the tool is able to glean from the class files, and allows the specification of additional dependencies. The message log tab displays a log of Jet processing actions, including information about any errors that the tool encounters. It is possible to save or clear the log at any time.

 

Once the appropriate settings are specified, a simple click on the Build button should build the EJB-Jar file. If all goes well, a dialog will appear shortly after with a message indicating that the build was successful. At that point, it is time to quit the Jet tool and start the WebSphere Administration Application (See Figure 2).

 

Figure 2 below illustrates the EJB deployment page in IBM Websphere's administrator utility. For each available JAR file, the administrator displays the Beans included in the JAR and their type. Once a JAR is selected and the Deploy button is clicked on, a dialog prompts for the container to deploy into.

 


 


Figure 2: The EJB Deployment Page in IBM's WebSphere Administrator Utility

 

Within this application there are three pages that control EJB deployment. The first is a global settings page. This page allows modifications to the host name, port, and protocol; the default protocol is CORBA. The second page allows the creation of EJB containers. For each container, it is necessary to specify a container name, the class file that contains the code that implements the container object (typically com.ibm.ejs.container.EJSSessionContainer or com.ibm.ejs.container.EJSEntityContainer), and the directory to install deployed EJB-Jars. At the bottom of the form is a panel that lists all of the EJB Jar files deployed into the container.

 

It is necessary to create separate containers for entity beans and session beans, and to create a separate entity bean container for each different database connection to properly support entity beans that represent tables in different databases. For each entity bean, the Container Definition allows the setting of the JDBC URL that an entity container should use to connect to its datasource, as well as the User ID and password that the container should use to authenticate itself to the database.

 

The third page in the Administration tool, which must be used to deploy the EJBs, is the Jar File Information and Deployment page. This page lists the EJB Jar files that are available in the deployable EJBs directory within the WebSphere directory tree, displays their contents, and shows which containers they are deployed into. The deploy button can be used to deploy or redeploy an EJB-Jar. When using this feature, the Deployment tool generates the container classes, updates the server properties, and copies the EJB Jar file into the target directory  specified for the container. If  a container managed entity bean is being deployed, the deployment process creates database tables that reflect the structure of the bean. Once again, if all goes well, the EJB should be installed. It will be necessary to restart the application server (the safest thing is to restart the computer) so that it can read the bean information at startup and be ready to execute bean code. The only work left to do at this point is to write a client.

 

After working with two application servers (BEA WebLogic and IBM WebSphere), it should be clear that the process of installing and configuring them is not for the faint of heart. It can take a while to get WebSphere to the point where EJBs can run correctly. First, getting WebSphere installed and talking to the Web server may take several tries. While the Jet tool and the Administrative screens that IBM has provided facilitate EJB JAR file creation and deployment, the fact that they are disconnected makes the process more complex than it ultimately needs to be.

 

ONLINE RESOURCES

 

Sun's Enterprise JavaBean specification
java.sun.com/products/ejb

BEA Weblogic
weblogic.beasys.com/index.htm

IBM WebSphere
www.software.ibm.com/webservers

Persistence PowerTier
www.persistence.com/Products/index.html

Novera jBusiness4
www.novera.com/products/index.shtml

CNN
www.cnn.com

Inprise JBuilder 2
www.Borland.com

Symantec Visual Café
cafe.symantec.com

 

As an application server, WebSphere warrants serious consideration; it's a very serious product with a wide range of features. In its current incarnation, its focus is on deploying servlets, JSP, and XML based applications. It should become clear from working with WebSphere that IBM is somewhat reticent to declare EJB technology quite ready for serious application development, but rather a technology that developers need to learn about. It is expected that IBM will increasingly emphasize EJB implementation as the specification matures and the announced "engagement" between CORBA and EJB begins to look more like a marriage.