Previous     Contents     Index     Next     
iPlanet Application Server Developer's Guide



Chapter 5   Using Session EJBs to Manage Business Rules


This chapter describes how to create session EJBs that encapsulate an application's business rules and logic. Specifically, this chapter explains how to use session beans to encapsulate repetitive, time bound, and user-dependent tasks that represent the transient needs of a single, specific user.

This chapter includes the following sections:



Introducing Session EJBs

Much of a standard, distributed application consists of logical code units that perform repetitive, time-bound, and user-dependent tasks. These tasks can be simple or complex, and are often needed in different applications. For example, banking applications must verify a user's account ID and balances before performing any transaction. These tasks define the business rules and logic that you use to run your business. Such discrete tasks, transient by nature, are candidates for session EJBs.

Session EJBs are self-contained code units that represent client-specific generic object instances. These objects are transient in nature, created and freed throughout an application's life on an as-needed basis. For example, the shopping cart employed by many web-based, online shopping applications is a typical session bean. It is created by the online shopping application only when an item is chosen. When an item selection is completed, the item prices in the cart are calculated, the order is placed, and the shopping cart object is freed. A user can continue browsing merchandise in the online catalogue, and if the user decides to place another order, a new shopping cart is created.

Often, a session bean has no dependencies on or connections to other application objects. For example, a shopping cart bean might have a data list member for storing item information, a data member for storing the total cost of items currently in the cart, and methods for adding, subtracting, reporting, and totaling items. On the other hand, the shopping cart might not have a live connection to the database of all available items for purchase.

Session beans can either be stateless or stateful. A stateless session bean encapsulates a temporary piece of business logic needed by a specific client for a limited time span. A stateful session bean is transient, but uses a conversational state to preserve information about its contents and values between client calls. The conversational state enables the bean's container to maintain information about the session bean state and to recreate the state at a later point in program execution when needed.

The defining characteristics of a session bean have to do with its non-persistent, independent status within an application. One way to think of a session bean is as a temporary, logical extension of a client application that runs on the application server. A session bean:

  • Executes for a single client.

  • Updates data in an underlying database.

  • Is short lived.

Generally, a session bean does not represent shared data in a database, but obtains a data snapshot. However, a bean can update data. Optionally, a session bean can also be transaction aware. Its operations can take place in the context of a transaction managed by the bean.

A client accesses a session bean through the bean's remote interface, EJBObject. An EJB object is a remote Java programming language object accessible from the client through standard Java APIs for remote object calls. The EJB lives in the container from its creation to its destruction, and the container manages the EJB's life cycle and support services. Where an EJB resides or executes is transparent to the client. Finally, multiple EJBs can be installed in a single container. The container provides services that allow clients to look up the interfaces of installed EJB classes through the Java Naming and Directory Interface (JNDI).

A client never accesses session bean instances directly. Instead, a client uses the session bean's remote interface to access a bean instance. The EJB object class that implements a session bean's remote interface is provided by the container. At a minimum, an EJB object supports all java.ejb.EJBObject interface methods. This includes methods to obtain the session bean's home interface, to get the object's handle, to test if the object is identical to another object, and to remove the object. These methods are stipulated by the EJB specification. In addition, most EJB objects also support specific business logic methods. These methods are at the heart of an application.

All specifications are accessible from install_dir/ias/docs/index.htm, where install_dir is the location where the iPlanet Application Server is installed.



Session Bean Components



When programming a session bean, you must provide the following class files:

  • Enterprise bean remote interface, extending javax.ejb.EJBObject

  • Enterprise bean class definition

  • Enterprise bean home interface, extending javax.ejb.EJBHome

  • Enterprise bean metadata (Deployment Descriptors (DDs) and other configuration information)


Creating the Remote Interface

A session bean's remote interface defines a user's access to a bean's methods. All remote interfaces extend javax.ejb.EJBObject. For example:

import javax.ejb.*;
import java.rmi.*;
public interface MySessionBean extends EJBObject {
// define business method methods here....
}

The remote interface defines the session bean's business methods that a client calls. The business methods defined in the remote interface are executed by the bean's container at runtime. For each method you define in the remote interface, you must supply a corresponding method in the bean class itself. The corresponding method in the bean class must have the same signature.

Besides the business methods you define in the remote interface, the EJBObject interface defines several abstract methods that enable you to retrieve the bean's home interface, to retrieve the bean's handle (a unique identifier), to compare the bean to another bean to see if it is identical, and to free or remove the bean when it is no longer needed.

For more information about these built-in methods and how they are used, see the EJB specification. All specifications are accessible from install_dir/ias/docs/index.htm, where install_dir is the location where the iPlanet Application Server is installed.


Declaring vs. Implementing the Remote Interface

A bean class definition must include one matching method definition, including matching method names, arguments, and return types, for each method defined in the bean's remote interface. The EJB specification also permits the bean class to implement the remote interface directly, but recommends against this practice to avoid inadvertently passing a direct reference (through this) to a client in violation of the client-container-EJB protocol intended by the specification.


Creating the Class Definition

For a session bean, the bean class must be defined as public and cannot be abstract. The bean class must implement the javax.ejb.SessionBean interface. For example:

import java.rmi.*;
import java.util.*;
import javax.ejb.*;
public class MySessionBean implements SessionBean {
// Session Bean implementation. These methods must always included.
public void ejbActivate() throws RemoteException {
}
public void ejbPassivate() throws RemoteException {
}
public void ejbRemove() throws RemoteException{
}
public void setSessionContext(SessionContext ctx) throws RemoteException {
}

// other code omitted here....
}

The session bean must also implement one or more ejbCreate(...) methods. There must be one method for each way a client invokes the bean. For example:

public void ejbCreate() {
String[] userinfo = {"User Name", "Encrypted Password"} ;
}

Each ejbCreate(...) method must be declared as public, return void, and be named ejbCreate. Arguments must be legal Java RMI types. The throws clause may define application specific exceptions and may include java.rmi.RemoteException or java.ejb.CreateException.

All useful session beans also implement one or more business methods. These methods are usually unique to each bean and represent its particular functionality. For example, if a session bean manages user logins, it might include a unique function called ValidateLogin().

Business method names can be anything, but must not conflict with the method names used in the EJB architecture. Business methods must be declared as public. Method arguments and return value types must be legal for Java RMI. The throws clause may define application specific exceptions and must include java.rmi.RemoteException.

There is one interface implementation permitted in a session bean class definition, particularly javax.ejb.SessionSynchronization, that enables a session bean instance to be notified of transaction boundaries and synchronize its state with those transactions. For more information about this interface, see the EJB specification. All specifications are accessible from install_dir/ias/docs/index.htm, where install_dir is the location where the iPlanet Application Server is installed.


Session Timeout

The container removes inactive session beans after they are inactive for a specified (or default) time. This timeout value is set in the bean's deployment descriptor. For more information, see "EJB XML DTD."


Passivation and Activation

The container passivates session beans after they are inactive for a specified (or default) time. This timeout value is set in the bean's deployment descriptor. For more information, see "EJB XML DTD."

For more information about passivation, see the EJB specification. All specifications are accessible from install_dir/ias/docs/index.htm, where install_dir is the location where the iPlanet Application Server is installed.


Creating the Home Interface

The home interface defines the methods that enable a client using the application to create and remove session objects. A home interface always extends javax.ejb.EJBHome. For example:

import javax.ejb.*;
import java.rmi.*;

public interface MySessionBeanHome extends EJBHome {
   MySessionBean create() throws CreateException, RemoteException;
}

As this example illustrates, a session bean's home interface defines one or more create methods. Each method must be named create, and must correspond in number and argument types to an ejbCreate method defined in the session bean class. The return type for each create method, however, does not match its corresponding ejbCreate method's return type. Instead, it must return the session bean's remote interface type.

All exceptions defined in the throws clause of an ejbCreate method must be defined in the throws clause of the matching create method in the remote interface. In addition, the throws clause in the home interface must always include javax.ejb.CreateException.

All home interfaces automatically define two remove methods for destroying an EJB when it is no longer needed.



Note Do not override these methods.





Additional Session Bean Guidelines



Before deciding which parts of an application you can represent as session beans, you should know a few more things about session beans. A couple of these things are related to the EJB specification for session beans, and a couple are specific to the iPlanet Application Server and its support for session beans.


Creating Stateless or Stateful Beans

The EJB specification describes two state management modes for session beans:

  • STATELESS - the bean retains no state information between method calls, so any bean instance can service any client.

  • STATEFUL - the bean retains state information across methods and transactions, so a specific bean instance must be associated with a single client at all times.

If you use stateful session beans, co-locate the stateful beans with their clients. Also, use sticky load balancing to reduce the number of RPCs, especially for session beans that are passivated and activated frequently or for session beans that use many resources, such as database connections and handles.


Accessing iPlanet Application Server Functionality

You can develop session beans that adhere strictly to the EJB specification, you can develop session beans that take advantage of both the specification and additional, value-added iPlanet Application Server features, or you can develop session beans that adhere to the specification in non-iPlanet Application Server environments, but that take advantage of iPlanet Application Server features if they are available. Make the choice that is best for your intended deployment scenario.


Serializing Handles and References

The EJB specification indicates that to guarantee serializable bean references, you should use handles rather than direct references to EJBs.

In the iPlanet Application Server, direct references are also serializable. If you take advantage of this extension, be aware that not all vendors support it.


Managing Transactions

Many session beans interact with databases. You control bean transactions by using settings in the bean's property file. This permits specifying transaction attributes at bean deployment time.

You can choose between Container Managed Transaction or Bean Managed Transaction.

If the Container manages the transaction, there is no need to explicitly start, rollback, or commit transactions in the bean's database access methods.

By moving transaction management to the Container level, you gain the ability to place all the bean's activities—even those not directly tied to the database access—under the same transaction control as your database calls. This guarantees that all application parts controlled by Container run as part of the same transaction, and either everything the Container undertakes is committed, or it is rolled back in a failure case. In effect, a Container managed transactional state permits synchronizing the application without programming any synchronization routines.

If the session bean uses Bean Managed Transaction, then you have to explicitly code the transaction scope in the bean's methods.


Accessing Databases

Many session beans access and update data. Because session beans are transient, be careful about how accesses occur. In general, use the JDBC API to make calls, and always use the transaction and security management methods described in Chapter 8 " Handling Transactions with EJBs" to manage the transaction isolation level and transaction requirements at the bean level.

For details about database accesses, see Chapter 9 "Using JDBC for Database Access."


Session Bean Failover

The session bean failover feature allows conversational state recovery for stateful session beans when an iPlanet Application Server becomes unavailable due to a service loss. Supporting failover for stateful session beans is an iPlanet Application Server value-added feature. J2EE programs do not need any modification to support the iPlanet Application Server failover feature. Failover is handled by the container and is defined by the deployer in the deployment descriptor.

Imagine a corporate buyer performing online purchasing at an e-commerce web site. After spending hours shopping, the buyer has hundreds of items in their shopping cart (a stateful session bean). The system then has an unexpected fatal problem and the iPlanet Application Server instance becomes unavailable. Without failover capability, the failure would result in the buyer's shopping cart becoming empty; the stateful session bean's state would be lost. With the failover feature in place, the buyer is unaware of the system failure; the failover mechanism redirects the client to a running iPlanet Application Server instance that has the bean's state before the failure. The buyer's shopping cart contains the same selected items as it did before the failover took place.

Notable failover feature support for stateful session beans includes:

  • Failover is a value-added feature that supports J2EE programs.

  • Failover is transparent to the client; no special APIs are required.

  • Failover is handled by the container and configured by the deployer.

  • Distributed Store (DSync) is the enabling mechanism for restoring the state after a system failure.

  • Performance impact is minimal for stateful session beans that do not need failover support.


How to Configure a Stateful Bean with Failover

Configuring a stateful session bean for failover is a combination of configuring the bean with failover and DSync.

  • During installation or runtime, configure the server for DSync.

  • During deployment, configure the stateful session bean for failover.

To take advantage of the failover feature, the bean must be configured with both failover and DSync. The DSync mechanism saves the session bean's conversational state during runtime. The failover mechanism allows the container to detect a system failure and connects to another running iPlanet Application Server instance that has the saved session bean state.

For more information, see the Administrator's Guide for details on how to configure a stateful session bean with failover during deployment and how to configure DSync during runtime. For more information on configuring DSync during installation, see the Installation Guide.


How the Failover Process Works

Stateful bean failover is achieved with a combination of smart stubs and a distributed store. When a bean is deployed as a failover bean, the deployment tool generates special stubs. On a method invocation, the smart stubs detect failures and transparently relocate a bean to a new home potentially in a different engine. The stubs determine if the bean's reference has become stale by getting a connection exception from the dead bean. The stubs then do a home look up and obtain the remote interface. Once the bean is relocated, the stubs retry the method on the recovered bean. The container guarantees at-most-once semantics when trying a method.

The container uses a distributed store that is based on DSync to maintain the bean state. The bean state is saved at regular intervals and is automatically reinstated as part of the recovery process.

For more information on the deployment descriptors used by stateful session beans for failover, see Chapter 11 "Packaging for Deployment."


Failover Guidelines

Keep in mind the following guidelines when implementing failover:

  • Keep ejbPassivate() and ejbActivate() simple.

  • Use obj.remove() to remove a bean, not home.remove(handle). Association between a bean and its original home may not be preserved after failover.

  • Use judgement by carefully weighing the advantages of bean failover against the failover process performance cost.



    Note Do not configure every stateful bean with failover.



  • Remember, session bean state is conversational. Use entity beans for transactional data.

  • The time interval for saving a stateful session bean's state is configurable using the Administration Tool (under the EJB tab); the default is 10 seconds.

  • If the bean is transactional, timer-based state saving is automatically disabled during transactions. This ensures transactional data integrity in case of a server engine failure during the transaction. Transactional database updates are rolled back by the database if a failure occurs. The state of the recovered bean is whatever it was at the begining of the failed transaction. However, if the transaction proceeds smoothly, the bean state is saved when the transaction completes, and timer-based saving resumes until the next transaction begins.

  • If the bean implements the iPlanet Application Server provided com.netscape.server.ejb.IEBFoStateModification interface, the state saver can check if the state of the bean is modified or not before it performs the expensive save operation. This interface defines two methods:

       package com.netscape.server.ejb;

       public interface IEBFoStateModification {

          /**
           ** This method is called by the container to check if a bean
           ** instance is dirty.
           **/

          boolean isDirty();

          /**
           ** Sometimes the container performs immediate saves. Then it
           ** calls to reset the dirty state of the modified bean
           **/

          void setDirty(boolean dirty);

       }

    The user-supplied bean implementation has a boolean variable that tracks the modified state of the bean. This variable is consulted prior to any state saving.


How Often Is the State Saved?

A container with failover configured saves the bean state during runtime at regular intervals. The process for saving the state includes:

  • Saving at regular, configurable time intervals.

  • Saving on transaction boundaries, if the bean participates in transactions.

The regular time interval is configured in the Administration Tool.


How the State Is Saved

The process for state saving is as follows:

  • First, each stateful session bean's ejbPassivate() method is called.

  • Next, the bean's conversational state is serialized and saved to the distributed store.

  • Finally, the bean's ejbActivate() method is called.



    Note Saving a bean state is expensive because of the operations involved.




Previous     Contents     Index     Next     
Copyright © 2002 Sun Microsystems, Inc. All rights reserved.

Last Updated March 06, 2002