Sun Java System Application Server Standard and Enterprise Edition 7 2004Q2 Developer's Guide to Enterprise JavaBeans Technology |
Chapter 2
Using Session BeansThis section provides guidelines for creating session beans in the Sun Java System Application Server environment.
Note
If you are unfamiliar with session beans or the EJB technology, refer to the Java Software tutorials:
http://java.sun.com/j2ee/docs.html
Extensive information on session beans is contained in chapters 6, 7, and 8 of the Enterprise JavaBeans Specification, v2.0.
Overview material on the Sun Java System Application Server is contained in Sun Java System Application Server and Enterprise JavaBeans Technology and the Sun Java System Application Server Product Introduction.
This section addresses the following topics:
Extensive information on session beans is contained in the chapters 6, 7, and 8 of the Enterprise JavaBeans Specification, v2.0.
About Session BeansThis section provides an overview of what you need to be aware of about session beans in order to develop effective models for your business processes.
This section addresses the following topics:
Session Bean Characteristics
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 Sun Java System Application Server. Generally, a session bean does not represent shared data in a database, but obtains a data snapshot. However, a session bean can update data.
Session beans have the following characteristics:
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. Such discrete tasks, transient by nature, are candidates for session beans.
Sample Scenario
The shopping cart employed by many web-based, online shopping applications is a typical use for a session bean. It is created by the online shopping application only when an item is selected by the user. When selection is completed, the item prices in the cart are calculated, the order is placed, and the shopping cart object is released, or freed. A user can continue browsing merchandise in the online catalog, 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 at all.
The Container
Like an entity bean, a session bean can access a database through Java Database Connectivity (JDBC) calls. A session bean can also provide transaction settings. These transaction settings and JDBC calls are referenced by the session bean’s container, allowing it to participate in transaction managed by the container.
A container managing stateless session beans has a different charter from a container managing stateful session beans.
Stateless Container
The stateless container manages the stateless session beans, which, by definition, do not carry client-specific states. Therefore, all session beans (of a particular type) are considered equal.
A stateless session bean container uses a bean pool to service requests. The Sun Java System Application Server-specific XML file contains the properties that define the pool:
These properties are defined for the deployment descriptor in “Elements in the sun-ejb-jar.xml File” on page 181.
Stateful Container
The stateful container manages the stateful session beans (SFSBs), which, by definition, carry the client-specific state. There is a one-to-one relationship between the client and the SFSBs. At creation, each SFSB is given a unique session ID that is used to access the session bean so that an instance of an SFSB is accessed by a single client only.
SFSBs are managed using cache. The size and behavior of SFSBs cache can be controlled by specifying the following parameters:
The max-cache-size element specifies the maximum number of session beans that are held in cache. If the cache overflows (when the number of beans exceeds max-cache-size), the container then passivates some beans or writes out the serialized state of the bean into a file. The directory in which the file is created is obtained from the server.xml file using the configuration APIs.
These properties are defined in the deployment descriptor. See “Elements in the sun-ejb-jar.xml File” on page 181 for more information.
The passivated beans are stored on the file system.The session-store attribute in the server element in the server.xml file allows the administrator to specify the directory where passivated beans are stored. By default, passivated SFSBs are stored in application-specific subdirectories created under instance_dir/session-store.
Developing Session BeansWhen a client is done with the session bean, it is released, or freed. When designing an application, you should designate each temporary, single client object as a potential session bean.
The following sections discuss how to develop effective session beans:
Development Requirements
When developing a session bean, you must provide the following:
Requirements of a session bean implementation class:
- Implements the javax.ejb SessionBean interface.
- The class is defined as public, and cannot be defined as abstract or final.
- Implements one ejbCreate method that takes no arguments.
- Implements the business methods.
- Contains a public constructor with no parameters.
- Must not define the finalize method.
Determining Session Bean Usage
This section provides some guidelines for determining whether to implement stateful or stateless session beans.
Stateless Session Bean Considerations
You might choose a stateless session bean if any of these conditions exist:
- The bean’s state has no data for a specific client, that is, user conversational state does not have to be retained across method invocations on the bean.
- In a single method invocation, the bean performs an atomic task that is generic across all clients. For example, a stateless bean could be used to return the weather forecast based on a ZIP code.
- The bean fetches a set of read-only data (from a database) that is often used by clients. Such a bean, for example, could retrieve the table rows that represent the products that are on sale this month.
Use a stateless session bean to access data or perform transactional operations. Stateless session beans provide high scalability because a small number of such beans managed by the container in a stateless bean pool) can help serve a large number of clients. This is possible because stateless beans have no association with the clients. When a request for a service provided by a stateless session bean is received, the container is free to dispatch the request to any bean instance in the pool.
- The create method of the remote home interface must return the session bean’s remote interface.
- The create method of the local interface must return the session bean’s local interface.
- There can be no other create methods in the home interface.
- A stateless session bean must not implement the javax.ejb.SessionSynchronization interface.
Stateful Session Bean Considerations
SFSBs are appropriate if any of the following conditions are true:
- The bean’s state represents the interaction between the bean and a specific client.
- The bean needs to hold session state information about, or on behalf of, the client user across method invocations.
- The bean mediates between the client and the other components of the application, presenting a simplified view to the client.
- Behind the scenes, the bean manages the work flow of several enterprise beans.
- The application must accept requests from non-web-based clients as well as web-based clients, at the same time preserving session state information.
Because SFSBs are private to a client, their demand on server resources increases as the number of users accessing an application increases. The beans remain in the container until they are explicitly removed by the client, or are removed by the container when they are timed out.
The container needs to passivate SFSBs to secondary storage as its cache fills up and the beans in the cache timeout. If the client subsequently accesses the bean, the container is responsible for activating the bean. This passivation/activation process imposes a performance overhead on the server.
For information about how a stateful session bean’s state can be saved in a persistent store in case a server instance fails, see Stateful Session Bean Failover (Enterprise Edition).
Providing Interfaces
As the developer, you are responsible for providing interfaces for the bean. If you implement a remote view for your bean, provide a remote component interface and a remote home interface. If you implement a local view, provide a local component interface and a local home interface.
To use interfaces safely, you need to carefully consider potential deployment scenarios, then decide which interfaces can be local and which remote, and finally, develop the application code with these choices in mind.
The following sections discuss creating interfaces:
Creating a Remote Interface
A session bean’s remote interface defines a client’s access to a bean’s methods. All remote interfaces extend javax.ejb.EJBObject. For example:
import javax.ejb.*;
import java.rmi.*;
public interface MySession extends EJBObject {
// define business methods here...
public String getAccountname() throws RemoteException;
}For each method you define in the bean class, you must supply a corresponding method in the remote interface. The remote interface method must have the same name, signature, return type, and exceptions thrown as the corresponding method in the bean class. In addition, the remote interface method must throw a RemoteException.
For example, the implementation class for MySession might look like this:
public class MySessionBean implements SessionBean {
private String accountname;
public MySessionBean() { }
public void ejbCreate() { }
public String getAccountname() {
return accountname;
}
}Creating a Local Interface
The local interface may be defined for a bean during development to allow streamlined calls to the bean if a caller is in the same container, that is, running in the same address space or Java Virtual Machine (JVM). This improves the performance of applications in which co-location is planned.
However, the calling semantics of local interfaces are different from those of remote interfaces. For example, remote interfaces pass parameters using pass-by-value semantics, while local interfaces use pass-by-reference. As a developer, you must be aware of the potential sharing of objects passed through the local interface. In particular, be careful that the state of one enterprise bean is not assigned to the state of another. You must also exercise caution in determining which objects to pass across the local interface, particularly in the case where there is a change in transaction or security content.
The local interface extends the javax.ejb.EJBLocalObject interface, and is allowed to have super interfaces. The throws clause of a method defined in the local interface must not include java.rmi.RemoteException. For example:
import javax.ejb.*;
public interface MyLocalSession extends EJBLocalObject {
// define business method methods here....
}For each method defined in the local interface, there must be a matching method in the session bean’s class. The matching method must have the same name, the same number and types of arguments, and the same return type. All exceptions defined in the throws clause of the matching method of the session bean class must be defined in the throws clause of the method of the local interface. The methods should not throw a java.rmi.RemoteException.
Creating the Local Home Interface
The home interface defines the methods that enable a client using the application to create and remove session beans. An enterprise bean’s local home interface defines the methods that allow local clients to create, find, and remove EJB objects, as well as home business methods that are not specific to a bean instance (session beans do not have finders and home business methods). The local home interface is defined by you and implemented by the container. A client locates a session bean’s home interface using JNDI.
The local home interface allows a local client to:
A local home interface always extends javax.ejb.EJBLocalHome. For example:
import javax.ejb.*;
import java.rmi.*;public interface MySessionLocalBeanHome extends EJBLocalHome {
MySessionLocalBean create() throws CreateException;
}Create Methods
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 local 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.
Remove Methods
A remote client may remove a session object using the remove method on the javax.ejb.EJBObject interface, or the remove(Handle handle) method of the javax.ejb.EJBHome interface.
Because session objects do not have primary keys that are accessible to clients, invoking the javax.ejb.EBJHome.remove(Object primaryKey) method on a session results in javax.ejbRemoveException.
Creating the Remote Home Interface
The container provides the implementation of the remote home interface for each session bean that defines a remote home interface that is deployed in the container. The object that implements this is called a session EJBHome object. The remote home interface allows a client to do the following:
The remote home interface must extend the javax.ejb.EJBHome interface, and is allowed to have super interfaces. The methods defined in the interface must follow the rules for RMI/IIOP.
The remote home interface must define one or more create<METHOD>(...) methods.
A remote home interface always extends javax.ejb.EJBHome. For example:
import javax.ejb.*;
import java.rmi.*;public interface MySessionHome extends EJBHome {
MySession create() throws CreateException, RemoteException;
}As this example illustrates, a session bean’s home interface defines one or more create methods. 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 and java.rmi.RemoteException.
Note
For stateless session beans, the home interface must have exactly one create method and the bean must have exactly one ejbCreate method. Both methods take no arguments.
Creating the Bean Class Definition
For a session bean, the bean class must be defined as public, must not be final, and cannot be abstract. The bean class must implement the javax.ejb.SessionBean interface.
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() {
}
public void ejbPassivate() {
}
public void ejbRemove() {
}
public void setSessionContext(SessionContext ctx) {
}
// other code omitted here....
}The session bean must 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 java.ejb.CreateException.
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 defined in the EJB interfaces. 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.
Session Synchronization
There is one interface implementation permitted in an SFSB 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.
The javax.ejb.SessionSynchronization interface allows an SFSB instance to be notified by its container of transaction boundaries. A session bean class is optional to implement this interface. A session bean class should implement this interface only if you want to synchronize its state with the transactions. For example, an SFSB that implements this interface will get callbacks after a new transaction begins, but before a transaction commits, and after commitment.
For more information about this interface, see the Enterprise JavaBeans Specification, v2.0.
Note
The container will only invoke the session synchronization interface methods for SFSBs that use container-managed transactions.
Abstract Methods
Besides the business methods you define in the remote interface, the EJBObject interface defines several abstract methods that enable you to:
For more information about these built-in methods and how they can be used, see the Enterprise JavaBeans Specification, v2.0.
The deployment tools provided by the container are responsible for the generation of additional classes when the session bean is deployed.
Stateful Session Bean Failover (Enterprise Edition)An SFSB’s state can be saved in a persistent store in case a server instance fails. The state of an SFSB is saved to the persistent store at predefined points in its life cycle. This is called checkpointing. If SFSB checkpointing is enabled, checkpointing generally occurs after any transaction involving the SFSB is completed, even if the transaction rolls back.
However, if an SFSB participates in a bean-managed transaction, the transaction might be committed in the middle of the execution of a bean method. Since the bean’s state might be undergoing transition as a result of the method invocation, this is not an appropriate instant to checkpoint the bean’s state. In this case, the EJB container checkpoints the bean’s state at the end of the corresponding method, provided the bean is not in the scope of another transaction when that method ends. If a bean-managed transaction spans across multiple methods, checkpointing is delayed until there is no active transaction at the end of a subsequent method.
The state of an SFSB is not necessarily transactional and could be significantly modified as a result of non-transactional business methods. If this is the case for an SFSB, you can specify a list of checkpointed methods. If SFSB checkpointing is enabled, checkpointing occurs after any checkpointed methods are completed.
The following table lists the types of references that SFSB failover supports. All objects bound into an SFSB must be one of the supported types. In the table, No indicates that failover for the object type may not work in all cases and that no failover support is provided. However, failover may work in some cases for that object type. For example, failover may work because the class implementing that type is serializable.
For more information about the InitialContext, transaction recovery, and Administered Objects, see the Sun Java System Application Server Developer's Guide to J2EE Services and APIs.
You configure SFSB failover by:
- Specifying SFSB Methods to Be Checkpointed (optional)
Choosing a Persistence Store
Two types of persistent storage are supported for passivation and checkpointing of the SFSB state:
- The local file system - Allows a single server instance to recover the SFSB state after a failure and restart. This store also provides passivation and activation of the state to help control the amount of memory used. This option is not supported in a production environment that requires SFSB state persistence. This is the default storage mechanism.
- The high-availability database (HADB) - Allows a cluster of server instances to recover the SFSB state if any server instance fails. The HADB is also used as the passivation and activation store. Use this option in a production environment that requires SFSB state persistence. For information about how to set up and configure this database, see the Administration Guide.
You can choose the persistence store in the following ways:
Using the Administration Interface
You can use the Administration interface to choose the HADB persistence store. To use this tool, follow these steps:
- Open the Availability Service component under your server instance.
- Go to the Availability Service page.
- Check the Instance Level Availability box.
- Click on the Save button.
- Click Properties under Persistence Store Properties.
- In the Name field, type store-pool-jndi-name.
- In the Value field, type the JNDI name of the HADB JDBC Resource. The assumed default is jdbc/hastore. For more information, see the Administration Guide.
- Click on the Save button.
- Go to the server instance page.
- Apply Changes and restart the server.
For information about how to configure the HADB persistence store, see the Administration Guide.
If availability is disabled, the local file system is used for SFSB state passivation, but not persistence. To change the location where the SFSB state is stored, follow these steps:
Editing the server.xml File
The presence of the store-pool-jndi-name property in the server.xml file specifies that the HADB is used for SFSB state persistence. Note that availability-enabled="true" must also be set. The absence of this property and attribute specifies that the local file system is used. The element hierarchy in the server.xml file looks like this when the HADB is configured:
<server name="server1" ... >
...
<availability-service availability-enabled="true">
<persistence-store>
<property name="store-pool-jndi-name" value="jdbc/hastore"/>
</persistence-store>
</availability-service>
...
</server>For information about how to configure the persistence store, see the Administration Guide.
The session-store attribute in the server.xml file determines where the SFSB state is stored if the local file system is used for SFSB state persistence. For example:
<server name="server1" ... session-store="/export/sfsbstore">
These changes to the server.xml file take effect when you restart the server.
Enabling SFSB Checkpointing
SFSB checkpointing can be enabled at five different levels:
For SFSB checkpointing to be enabled at a given level, it must be enabled at all higher levels as well. For example, to enable SFSB checkpointing at the application level, you must also enable it at the server instance and EJB container levels.
The default for a given level is the setting at the next level up. For example, if SFSB checkpointing is enabled at the EJB container level, it is enabled by default at the application level.
When SFSB checkpointing is disabled at the server instance level (the default setting), enabling it at any other level has no effect. When SFSB checkpointing is enabled at the server instance level, it is enabled at all levels unless explicitly disabled.
The following sections describe how to enable SFSB checkpointing:
Server Instance and EJB Container Levels
To enable SFSB checkpointing at the server instance level, see Choosing a Persistence Store.
You can enable SFSB checkpointing at the EJB container level in the following ways:
Using the Administration Interface
To enable SFSB checkpointing at the EJB container level using the Administration interface, follow these steps:
- Open the Availability Service component under your server instance.
- Go to the Availability Service page.
- Make sure that Instance Level Availability is checked.
- Make sure that Ejb Container Availability is set to either Enabled or Specified by Instance.
- Click on the Save button.
- Go to the server instance page.
- Apply Changes and restart the server.
Using the asadmin Command
To enable SFSB checkpointing at the EJB container level, use the asadmin set command as follows, then restart the server:
asadmin set --user admin_user [--password admin_password] [--passwordfile password_file] [--host localhost] [--port 4848] [--secure | -s] instance_name.ejb-container.availabilityEnabled=true
Editing the server.xml File
To enable SFSB checkpointing at the EJB container level, set availability-enabled="true" in the ejb-container element of the server.xml file as follows, then restart the server:
<server name="server1">
...
<ejb-container ... availability-enabled="true"/>
...
</server>Application and EJB Module Levels
You can enable SFSB checkpointing at the application or EJB module level during deployment. For details, see “Deploying Enterprise Beans” on page 175.
As an alternative, you can edit the server.xml file. To enable SFSB checkpointing at the application level, set availability-enabled="true" in the j2ee-application element of the server.xml file as follows, then restart the server:
<server name="server1">
...
<applications>
...
<j2ee-application
name="MyApp"
location="instance_dir/applications/j2ee-apps/MyApp"
availability-enabled="true">
</j2ee-application>
...
</applications>
...
</server>To enable SFSB checkpointing at the EJB module level, set availability-enabled="true" in the ejb-module element of the server.xml file as follows, then restart the server:
<server name="server1">
...
<applications>
...
<ejb-module
name="MyBean"
location="instance_dir/applications/j2ee-modules/MyBean"
availability-enabled="true">
</ejb-module>
...
</applications>
...
</server>SFSB Level
To enable SFSB checkpointing at the SFSB level, set availability-enabled="true" in the ejb element of the SFSB’s sun-ejb-jar.xml file as follows:
<sun-ejb-jar>
...
<enterprise-beans>
...
<ejb availability-enabled="true">
<ejb-name>MySFSB</ejb-name>
</ejb>
...
</enterprise-beans>
</sun-ejb-jar>Specifying SFSB Methods to Be Checkpointed
If SFSB checkpointing is enabled, checkpointing generally occurs after any transaction involving the SFSB is completed, even if the transaction rolls back.
You can specify additional optional checkpointing of SFSBs at the end of non-transactional business methods that cause important modifications to the bean’s state. To do so, you specify a semicolon-separated list of method signatures in the checkpointed-methods element within the ejb element in sun-ejb-jar.xml. The listed methods must have the same signatures as those in the corresponding home or client interface of the SFSB, and the parameter class names must be fully qualified (for example, java.lang.String rather than just String).
For example:
<sun-ejb-jar>
...
<enterprise-beans>
...
<ejb availability-enabled="true">
<ejb-name>ShoppingCartEJB</ejb-name>
<checkpointed-methods>
create(int);addToCart(int, java.lang.String, CartDAO)
</checkpointed-methods>
</ejb>
...
</enterprise-beans>
</sun-ejb-jar>The non-transactional methods in the checkpointed-methods list can be:
- create() methods defined in the home interface of the SFSB, if you want to checkpoint the initial state of the SFSB immediately after creation
- For SFSBs using container managed transactions only, methods in the remote interface of the bean marked with the transaction attribute TX_NOT_SUPPORTED or TX_NEVER
- For SFSBs using bean managed transactions only, methods in which a bean managed transaction is neither started nor committed
Any other methods mentioned in this list are ignored. At the end of invocation of each of these methods, the EJB container saves the state of the SFSB to persistent store.
Restrictions and OptimizationsThis section discusses restrictions on developing session beans and provides some optimization guidelines:
Optimizing Session Bean Performance
For SFSBs, co-locating the stateful beans with their clients so that the client and bean are executing in the same process address space will improve performance.
Restricting Transactions
The following restrictions on transactions are enforced by the container and must be observed as you develop session beans:
- A session bean can participate in, at most, a single transaction at a time.
- If a session bean is participating in a transaction, a client cannot invoke a method on the bean such that the transaction attribute in the deployment descriptor would cause the container to execute the method in a different or unspecified transaction context or an exception is thrown.
- If a session bean instance is participating in a transaction, a client cannot invoke the remove method on the session object’s home or component interface object or an exception is thrown.