Previous Contents Index DocHome Next |
iPlanet Application Server Programmer's Guide (Java) |
Chapter 5 Using Session EJBs to Manage Business Rules
This chapter describes how to create session Enterprise JavaBeans (EJBs) that encapsulate your application's business rules and business objects.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
Introducing Session EJBs
Much of a standard, distributed application consists of logical units of code that perform repetitive, time-bound, and user-dependent tasks. These tasks can be simple or complex, and they are often needed in different applications. For example, banking applications must verify a user's account ID and balances before performing a fund transfer of any kind. These kinds of tasks define the business rules and business logic that you use to run your business. Such discrete tasks, transient by nature, are perfect candidates for session Enterprise JavaBeans (EJBs).Session EJBs are self-contained units of code that represent client-specific instances of generic objects. These objects are transient in nature, created and freed throughout the life of the application on an as-needed basis. For example, the "shopping cart" employed by many web-based, on-line shopping applications is a typical session bean. It is created by the on-line shopping application only when you start choosing items to buy. When you finish selecting items, the price of the items in your cart is calculated, your order is placed, and the shopping cart object is freed. You can continue to browse merchandise in the on-line catalogue, and if you decide the place another order, a new shopping cart is created for you.
Often, a session EJB 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 items available 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, uses a "conversational state" to preserve information about its contents and values between client calls. The conversational state enables the container to maintain information about the state of the session bean and to recreate that 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's application that runs instead on the application server. A session bean:
Generally, a session bean does not represent shared data in a database, but obtains a snapshot of data. The bean can, however, 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 that accesses it. 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 instances of a session bean 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 of the methods of the java.ejb.EJBObject interface. This includes methods to obtain the home interface for the session bean, 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. (All specifications are accessible from installdir/iAS/docs/index.htm, where installdir is the location in which you installed iAS.)
In addition, most EJB objects also support specific business logic methods. These are the methods at the heart of your applications.
Session Bean Components
When you code 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 meta-data (deployment descriptors 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 implemented by the bean's container at run time. 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 home interface for the bean, to retrieve the bean's handle, which is its 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 to be used, see the EJB Specification. All specifications are accessible from installdir/iAS/docs/index.htm, where installdir is the location in which you installed iAS.
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 (via 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 should be one such method for each way a client is allowed to invoke 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, if any, must be legal types for Java RMI. The throws clause, may define application-specific exceptions, 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 you define a session bean to manage user logins, it might include a unique function called ValidateLogin().
Business method names can be anything you want, but must not conflict with the names of methods 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 installdir/iAS/docs/index.htm, where installdir is the location in which you installed iAS.
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 XML Deployment Descriptor (DD) file. For more information, see "EJB XML DTD" in "Packaging for Deployment".
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" in "Packaging for Deployment".For more information about passivation, see the EJB specification. All specifications are accessible from installdir/ias/docs/index.htm, where installdir is the location in which you installed iAS.
Creating the Home Interface
The home interface defines the methods that enable a client using your 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 such method must be named create, and must correspond in number and type of arguments to an ejbCreate method defined in the session bean class. The return type for each create method, however, does not match the return type of its corresponding ejbCreate method. 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. Do not override these methods.
Additional Session Bean Guidelines
Before you decide what parts of your 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 iAS 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.
If you decide to use stateful session beans, plan to co-locate stateful beans with their clients. Also, use sticky load balancing to reduce the number of remote procedure calls, especially for session beans that are passivated and activated frequently or for session beans that use many resources, such as database connections and handles.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.
Accessing iAS Functionality
You can develop session beans that adhere strictly to the EJB Specification, you can develop session beans that take advantage both of the specification and additional, value-added iAS features, and you can develop session beans that adhere to the specification in non-iAS environments, but that take advantage of iAS features if they are available. Make the choice that is best for your intended deployment scenario.iAS offers several features through the iAS container and iAS APIs that enable your applications to take programmatic advantage of specific features of the iAS environment. You can embed API calls in your session beans if you plan on using those beans only in the iAS environment.
For example, you can trigger a named application event from an EJB using the IAppEventMgr interface, using the following steps and example:
First obtain an instance of com.kivasoft.IContext by casting javax.ejb.SessionContext or javax.ejb.EntityContext to IServerContext.
Next, use the GetAppEventMgr() method in the GXContext class to create an IAppEventMgr object.
Finally, trigger the application event with triggerEvent().
javax.ejb.SessionContext m_ctx;
....
com.netscape.server.IServerContext sc;
sc = (com.netscape.server.IServerContext) m_ctx;
com.kivasoft.IContext kivaContext = sc.getContext();
IAppEventMgr mgr = com.kivasoft.dlm.GXContext.GetAppEventMgr(ic);
mgr.triggerEvent("eventName");
Serializing Handles and References
The EJB Specification indicates that to guarantee serializable bean references, you should use handles rather than direct references to EJBs.iAS direct references are also serializable. You may wish to take advantage of this extension, but you should be aware that not all vendors support it.
Managing Transactions
Many session beans interact with databases. You can control transactions in beans using settings in the bean's property file. This permits you to specify transaction attributes at bean deployment time. By having a bean handle transaction management you are freed from having explicitly to start, roll back, or commit transactions in the bean's database access methods.By moving transaction management to the bean level, you gain the ability to place all of a bean's activitieseven those not directly tied to database accessunder the same transaction control as your database calls. This guarantees that all parts of your application controlled by a session bean run as part of the same transaction, and either everything the bean undertakes is committed, or is rolled back in the case of failure. In effect, bean-managed transactional state permits you to synchronize your application without having to code any synchronization routines.
Committing a Transaction
When a session bean signals that it is time to commit a transaction, the actual commit process is handled by the bean's container. Besides affecting the data your application processes, commit time also affects the state of a session bean. The iAS container implements commit option C as described in the EJB specification.When a commit occurs, it signals to the container that the session bean has completed its useful work, and should synchronize its state with the underlying data store. The container permits the transaction to complete, and then frees the bean. Result sets associated with a committed transaction are no longer valid. Subsequent requests for the same bean cause the container to issue a load to synchronize state with the underlying data store.
Note that transactions begun in the container are implicitly committed. Also, any participant can roll back a transaction. For more information about transactions, see Chapter 7 " Handling Transactions with EJBs".
Accessing Databases
Many session beans access and even update data. Because of the transient nature of session beans, however, be careful about how that access takes place. In general, use the JDBC API to make your calls, and always use the transaction and security management methods described in Chapter 7 " Handling Transactions with EJBs" to manage transaction isolation level and transaction requirements at the bean level.For more information see Chapter 8 , "Using JDBC for Database Access."
Session Bean Failover
The session bean failover feature allows conversational state recovery for stateful session beans in the case of an iAS server becoming unavailable due to a system crash or power failure. Supporting failover for stateful session beans is an iAS value-added feature. J2EE programs do not need any modification to support this iAS failover feature. Failover is handled by the container and is defined by the deployer in the deployment descriptor.Imagine a corporate buyer performing on-line 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 instance of the iAS server becomes unavailable. Without failover capability, the failure would result in the buyer's shopping cart becoming empty; the state of the stateful session bean 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 instance of the iAS server that has the state of the bean before the failure. The buyer's shopping cart will then have the same selected items as before the failover took place.
Notable features of the failover support for stateful session beans include:
Failover is a value-added feature that supports J2EE programs.
Failover is transparent to the client; no special APIs are required for the client to take advantage of this feature.
Failover is handled by the container and configured by the deployer.
Distributed Store (DSync) is the enabling mechanism for restoring 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 capability is a combination of configuring the bean with failover and Distributed Store (DSync).
During installation or during runtime, configure server for DSync.
In order to fully take advantage of the failover feature, the bean must have configured both failover and DSync. The DSync mechanism saves the conversational state of the session bean during runtime. The failover mechanism, allows the container to detect a system failure and then connect to another running iAS instance with the saved session bean state.During deployment, configure the stateful session bean with failover capability.
Refer to the Administration Guide for details on how to configure a stateful session bean with failover during deployment and how to configure DSync during runtime. Refer to the Installation Guide for details on configuring DSync during installation.
How the Failover Process Works
Failover of stateful beans 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 methd invocation, these smart stubs can detect failure and transparently relocate a bean to a new home, potentially in a different engine. Once the bean is relocated, the stub retries 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 state of a bean. The state of the bean is saved at regular intervals, and automatically reinstated as part of the recovery process.
How often is the State Saved
An container with failover configured, saves the bean states during runtime at regular intervals. The process for saving state includes:
Saving at regular, configurable time intervals.
The regular time interval is configured by the iAS Deployment Tool.Also saved on transaction boundaries, if the bean participates in transactions.
How the State is Saved
The process for saving the state is as follows:
First, each stateful session bean's ejbPassivate() method is called.
Note Saving the state for a bean is quite expensive because of the operations involved.The bean's conversational state is then serialized and saved to the distributed store.
How the Failover Process Works
Session beans with failover configured, have smart stubs that detect session bean failures and recreate new bean references when a failure occurs. The stubs determine that the Bean's reference has become stale by getting a connect exception from the dead bean. The stub then does a look up of the home and gets the remote interface.See , "Packaging for Deployment," for a description of the deployment descriptors used by stateful session beans for failover.
Failover Guidelines
Keep in mind the following suggestions and 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 it's original home may be preserved after failover.
Use judgement by carefully weighing the advantages of bean failover against the performance cost of the failover process. Do not make every stateful bean require failover.
Remember, session bean state is conversational. Use entity beans for transactional data.
Previous Contents Index DocHome Next
Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.
Last Updated June 25, 2000