Chapter 4: Session Beans


Chapter 4: Session Beans

Introduction

A session bean is a business object, since it typically implements a business process. In practice, the functionality of a session bean can constitute, for example, setting up a balance sheet in a bookkeeping system, executing transfer of funds in banking software, or managing a materials supply depot.

Logically, a session bean is viewed as the server-side extension of the client program. A client has exclusive access via the EJB container to a particular instance of a session bean and can use its functionality. The notion of "client" extends also to other beans on a server and client programs on a client computer. For the implementation of its functionality a session bean can use other enterprise beans as well as the services that the EJB container and J2EE Application server provide. (See Figure 4-1.)

click to expand
Figure 4-1: Overview of a session bean.

When a client uses a session bean, it can execute various actions that lead to changes of state, that is, to changes in the data of enterprise beans. One distinguishes persistent and transient changes of state:

  • A persistent change of state remains over multiple sessions of the client. Altered data, for example, can be stored in a database. Session beans themselves do not have a persistent state, but use entity beans for the storage of persistent data (see Chapter 5, on entity beans) or, for example, access a database directly via JDBC.

  • A transient change of state lasts only for the duration of a session. The transient state thereby describes the state of the session of the conversation between client and server. Therefore, one speaks here also of a conversational state. The transient state is stored partly by the client and partly by the session bean. Therefore, the session bean can also be viewed as a logical extension of the client.

There are two types of session beans: stateless session beans and stateful session beans. In contrast to the stateful session beans, the stateless session beans do not have a conversational state. This means that no application method of a stateless session bean alters the state of a bean instance.

One must always keep the two types separate, since the EJB container treats them differently in managing bean instances. This affects the programming of methods for state management. These methods are called by the EJB container at run time to inform the bean instance about a state change. In the section on the life cycle of a session bean instance we shall go into the precise differences.

Methods of session beans can be executed in a transaction. This depends on whether the session bean uses explicit transactions or whether the EJB container is instructed by the configuration to guarantee a particular transactional behavior. A transaction guarantees that the corresponding method either is successfully executed or is made completely revocable. Thus there are no inconsistent states in the case of an error. Since the subject of transactions is rather complex, it will be dealt with in detail in Chapter 7.



Concepts

Conversational State

A session bean offers services to its client in the form of methods. As a rule, the client calls a number of methods to achieve its goal. A call to a method can access an available service by writing, for example by changing the data in a database. The altered data are available to all clients and influence the results of subsequent method calls for various beans.

A method call can also itself change the state of the session bean instance itself (that is, its instance variables). The session bean instance is then stateful. The state of a session bean instance can be influenced only by method calls to the corresponding instance.

This state of an instance of a stateful session bean is called the conversational state (Figure 4-2). The EJB specification defines the conversational state as the state of all attributes of a session bean instance including the transitive hull of all objects that are reachable via Java references by the session bean instance. The conversational state is thus constructed out of all attributes and applied resources of the session bean. In practice, the conversational state consists, for example, of attribute values, open resource connections, database connections, references to other beans, and similar resources.

click to expand
Figure 4-2: Conversational state.

The conversational state remains only for the duration of a session of a client and is exclusively at this client's disposal. For this reason the session bean is understood to be a logical server-side extension of the client.

When a session bean instance stores its state for precisely one client, then each client requires its own bean instance. In order to prevent the unlimited growth of stateful session beans on the server, the EJB container employs a strategy of periodic decommissioning of instances from active storage. This decommissioning is called passivation, while a restoration is called activation.

During passivation the EJB container writes the state of a stateful session bean to a secondary storage medium (for example, to the hard drive). For this the serialization of Java objects is commonly used, which is part of the language definition of Java itself. This mechanism transforms Java objects into a byte stream, which, for example, can simply be written to a file. The opposite mechanism is called deserialization and is used during activation. Here the byte stream is retransformed into Java objects.

With the aid of these mechanisms (which, moreover, can be used only with session beans with a conversational state) the EJB container can work with a limited number of session bean instances in order to conserve available resources. If more bean instances are necessary, then instances that are not immediately needed can be stored. If a stored instance is again needed, then first another bean instance must be removed from active memory. Then the required bean is fetched into active memory. Here the EJB container uses a classical cache procedure. One strategy is to remove the bean instance that has gone unused the longest (LRU = least recently used). The maximum number of bean instances with which the EJB container can work is generally a configurable number.

Yet there is a problem with this mechanism: Not all Java objects can be simply serialized. For example, a socket or database connection cannot be simply written to the hard drive. The Java language definition requires all Java classes whose objects are to be serializable to implement the interface java.io.Serializable. Logically, in the Java class library the only classes that implement the interface are those whose objects are serializable. The EJB specification defines more precisely the conditions that objects of the conversational state of a session bean must satisfy:

  • Serializable object;

  • Reference to NULL;

  • Reference to a remote interface;

  • Reference to a home interface;

  • Reference to a local interface;

  • Reference to a local home interface;

  • Reference to the SessionContext;

  • Reference to the JNDI naming service of the bean environment;

  • Reference to the interface; UserTransaction;

  • Reference to a resource factory (to be discused later).

A session bean instance is always notified before its passivation to a secondary storage medium via a call to the method ejbPassivate. The session bean instance must then establish the above-named conditions. This means, for example, that resources and database connections must be closed. To avoid problems in serialization, all references to additional resources must be declared transient. If the session bean instance is again brought into active memory, then it will be notified via a call to the method ejbActivate. Then, for example, it can reestablish its resources and database connections and reset all variables.

Stateless and Stateful Session Beans

Session beans can have their own conversational state or be stateless (Figure 4-3). Based on these properties we distinguish two types of session beans:

  • Stateless session beans;

  • Stateful session beans.

click to expand
Figure 4-3: Stateful and stateless session beans.

Whenever a stateful session bean is newly generated, its state must be initialized. For this purpose it offers several create methods, to which the necessary data are passed as parameters by the client. A stateless session bean does not need to initialize a state. Therefore, it always has only one create method without parameters. For each session bean class there is a definition in the deployment descriptor telling which type it belongs to and the methods it offers.

This distinction between the two types helps the EJB container in the management of bean instances. In order to minimize resource requirements and maintain high performance, the EJB container employs management strategies that avoid as far as possible the generation and destruction of Java objects.

An instance of a stateless session bean can be used by the EJB container for another client after each method call. Since these possess no conversational state, the sequential method calls of a client can also be processed by various instances. An instance of a stateless session bean is thus available exclusively for a given client only for the duration of the method call. The EJB container divides the method calls into a pool with a fixed number of bean instances. The number of required bean instances is thus much smaller than the number of parallel client sessions.

In the case of stateful session beans the EJB container has another problem to solve. In order for the conversational state to remain and be available exclusively to a client during a session, each client requires its own session bean instance. Thus each instance of a stateful session bean is always available to only a single client for the duration of a session.

In order to keep the number of bean instances under control even in the case of a very large number of parallel clients, a particular strategy is employed. During activation or passivation a session bean can be removed from active memory and be reloaded at a later time (compare the implementations in the preceding section).

The crucial difference is that activation and passivation are necessary only for stateful session beans. This difference was of great enough significance for the division in the EJB concept into two classes of session beans.

The EJB container can thus work significantly more efficiently with stateless session beans than with stateful session beans. The serialization and deserialization of Java objects is a relatively expensive operation; that is, it requires a great deal of CPU time. Therefore, the implementation of stateless session beans pays off particularly well when there are many parallel clients to serve. A comparison with web servers may be useful here: One of the reasons for the success of the worldwide web is that a web server can work with static web pages in stateless mode and thereby serve many parallel clients.

Due to their higher demand on resources, stateful session beans are sometimes called heavyweight beans, while stateless session beans are known as lightweight beans.

Stateless session beans are nevertheless suitable for particular applications. Table 4-1 summarizes the differences between stateless and stateful session beans.

Table 4-1: Comparison of stateless and stateful session beans.

Stateless Session Beans

Stateful Session Beans

Have no conversational state

Have a conversational state

Are lightweight

Are heavyweight

Are not activated and passivated

Are activated and passivated

Instance is available to a client for the duration of method calls

Instance is available to a client for the duration of multiple method calls

Session Beans from the Client's Point of View

In dealing with EJB it is important to note the two different points of view: the client's view and the container's view. The client's view is concerned with what functionality is provided and how to interact with beans, while the container's view is more concerned with how the functionality is provided to the client in the most efficient manner.

The client has a very simple view of session beans. The EJB container conceals the mechanisms for managing bean instances from the client. How the client uses a session bean depends greatly on whether the client is located in the same Java process as the session bean.

Local vs. Remote Client View

The remote client view is the viewpoint of the client toward a session bean that is located in a different Java process from that of the client itself. The remote client view is the standard case of the client's view of a session bean. The local client view has existed only since version 2.0 of the EJB specification. The remote client view is used by, for example, client applications installed on client computers that use Enterprise Beans of an application server over a network. The remote client view is also used by enterprise beans that in fulfilling their mission use other enterprise beans that are installed on another, remote, application server.

Using the method create of the home object (compare in this regard Chapter 3) the client can create new session beans of a particular class. The session bean is available exclusively to that client until it deletes it via a call to the method remove on the remote object. As long as the session bean exists the client can call its methods via the remote object. The parameters and return values of the methods that the client calls via the remote object are passed under the call by value paradigm (as a copy). These semantics of a method call are determined by Java RMI, which is the basis of the remote-client-view.

The local client view is the viewpoint of the client toward a session bean that is located in the same process as the client itself. This could involve, for example, enterprise beans that in carrying out their mission use other enterprise beans that are installed on the same application server. Another example is that of server-side JMS clients or servlets that perform their services in the same Java process (that is, in the same application server) as the respective session bean.

With the method create of the local home object (see in this regard Chapter 3) the client can create new session beans of a particular class. The session bean is available exclusively to that client until it deletes it via a call to the method remove on the local object. As long as the session bean exists the client can call its methods via the local object. The parameters and return values of the methods that the client calls via the remote object are passed under the call by reference paradigm. The semantics of a method call are determined by the programming language Java. From the point of view of the client this is the crucial difference from the remote client view.

The bean developer determines whether a session bean is to be used with the local or remote client view. Based on the specification an enterprise bean should support either the local or remote client view. Theoretically, it would be possible for an enterprise bean to support both the local and remote client views. A particular client programs a particular session bean in each case either with respect to the local or remote interface of the session bean. If the client is not located in the same Java process as the enterprise bean, it must use the remote client view. If in this case the session bean offers only a local client view, the client cannot use the session bean. If the client is located in the same Java process as the session bean, then it will use the local client view (provided that the session bean offers it), since run-time efficiency is significantly greater than with the remote client view (there is no RMI overhead). If the session bean supports only the remote client view and the client is located in the same process as the session bean, then the client can nevertheless use the bean.

Stateless and Stateful Session Beans

The client need make no distinction in using stateful or stateless session beans. The client may not even know whether it is dealing with a stateless or stateful session bean.

The client must distinguish four states. These result from the fact that the client does not work directly with the bean instance. The client works with proxy objects of the EJB container (local home and local object or home and remote object) that delegate the respective calls to the actual bean instance:

  1. Nonexistent: The client has no reference to the remote or local object. From its perspective there thus exists no session bean instance on the server.

  2. Existent and referenced: The client possesses a valid reference to the remote or local object and can thereby access the session bean instance indirectly.

  3. Nonexistent, but referenced: This state is important for error handling. After the client has deleted the session bean instance with remove, the remote or local object no longer represents a valid reference. If the client nonetheless calls a method on the remote or local object, an exception is triggered, since the EJB container has no available bean instance for this call. The EJB container also deletes bean instances that have not been used for a long time (Timeout) or those for which a system error has occurred. The client then comes into this state automatically.

  4. Existent, but not referenced: The client deletes its reference to the home or local home object without first executing the method remove. After a certain period of time the EJB container deletes the bean instance (Timeout).

Life Cycle of a Session Bean Instance

As already mentioned, a session bean instance assumes various states during its lifetime. Transitions from one state to another are initiated by the client (e.g., with create and remove method calls) and the EJB container (via the management of its resources). The state transitions are managed exclusively by the EJB container (by calling Callback methods).

In order for the EJB container to be able to manage the state transition of a session bean instance, the bean class must implement the interface javax.ejb.SessionBean. The interface represents a sort of contract between the EJB container and the session bean. The EJB container is under obligation to notify the session bean instance about an impending state transition by a call to the relevant methods in the interface. The bean instance must ensure that its state is compatible with the following state.

The life cycles of stateless and stateful session beans are not the same, and they will be presented in detail later. On the other hand, whether a session bean supports the remote or local client view is immaterial as regards the life cycle. A detailed understanding of the life cycle of a session bean instance is a prerequisite for developing them.

Stateless Session Beans

An instance of a stateless session bean knows only two different states.

  • Nonexistent: The instance does not exist.

  • Pooled Ready: The instance exists and is available for method calls.

Figure 4-4 shows the life cycle of a stateless session bean. The figure distinguishes the cases of whether the EJB container or the client effects a state transition.

click to expand
Figure 4-4: Life cycle of a stateless session bean instance.

The EJB container manages the bean instances. If it requires an instance, then it first generates an instance of the corresponding bean class. Then it calls the method setSessionContext and thereby informs the instance of its session context. The session context enables the instance to access its environment (identity and role of the client, transaction context) and also to access the EJB container.

Then the EJB container calls the method ejbCreate, after which the bean instance is in the state Pooled Ready. It is kept in readiness by the EJB container in a pool with other instances of its bean class.

The method ejbCreate corresponds to the method create in the home or local home interface, with which the client can obtain for itself a new instance. A client's call can nonetheless be seen as completely independent of a call of the EJB container. If the client calls create for a stateless session bean, it obtains as a result a local or remote object (depending on which client view it uses) that is only a reference to the bean class and not to a concrete bean instance.

For each client call of an application method an arbitrary bean instance is taken from the pool. For the bean instance to be able to execute the method, the correct environment for it must first be created (for example, by the initialization of the session context, the transaction context and the identity of the client are announced to it). Now the EJB container can proceed with the client call to the bean instance. After the method has been executed, the instance is returned to the pool.

By this mechanism it is ensured that a bean instance always executes only one client method call at a time. The EJB container serializes all calls for the bean instance or uses multiple separate instances to handle the requests. The implementation of a bean thus does not have to concern itself with accesses via parallel threads.

An error can occur in the execution of a method. Declared exceptions of the method are simply passed along to the client, and the instance is again taken into the pool. However, if an exception of type java.lang.RuntimeException is triggered, which does not have to be declared, then the EJB container experiences a system error. This exception is also passed to the client. The bean instance, however, is not taken up again into the pool, but is removed and discarded.

The EJB container can limit the number of bean instances in the pool. To do this it first calls the method ejbRemove on the bean instance to inform the instance of the impending deletion, and then discards the instance. At a later time the garbage collection utility will delete the instance. All commonly used EJB implementations provide the functionality of finely controlling the number of bean instances contained within a pool.

Stateful Session Beans

The life cycle of stateful session beans is more complex than that of stateless session beans. Four states are distinguished:

  • Nonexistent: The session bean instance does not exist.

  • Ready: The session bean instance exists and was allocated to a client. It is available for method calls or can be passivated by the EJB container in this state.

  • Ready in TA: The session bean instance is engaged in a transaction and is waiting for a client method call (see Chapter 7, Transactions). The EJB container is not allowed to passivate instances engaged in transactions.

  • Passivated: The session bean instance was removed temporarily from active memory, but it is still allocated to a client. When the client wishes to execute a method, the EJB container must first reactivate the instance.

Figure 4-5 shows the life cycle of a stateful session bean. A distinction is made as to whether the EJB container or the client is responsible for a state transition.

click to expand
Figure 4-5: Life cycle of a stateful session bean instance.

In contrast to the stateless session beans, the EJB specification does not provide a pool for stateful session beans. The life-cycle of a stateful session bean is tightly coupled to its client.

Whenever the client calls a create method on the (local) home object to obtain a new session bean, the EJB container makes available exclusively to the client a new bean instance. The EJB container first generates an instance of the relevant bean class and informs it of the session context. Then the client method call is relayed to the corresponding bean instance ejbCreate method. Using parameters this method initializes the state of the bean instance. Then the bean instance is in the state Ready.

If at a later time the client no longer needs the session bean and calls the method remove on the remote or local object, the bean instance is removed from the EJB container. The EJB container calls the method ejbRemove in order to inform it about the impending removal. Then the situation will be as if the bean instance no longer existed, even though the garbage collector will delete the bean instance only at a later point in time.

An individual bean instance is required for each concurrent client that uses a stateful session bean. An EJB container must nevertheless limit the number of bean instances in active memory. Using passivation and activation it has the ability to remove bean instances temporarily from active memory. Before a bean is passivated, the EJB container calls the method ejbPassivate to inform the bean of its impending change of state. Upon activation the bean instance is first reloaded into active memory and then informed of the fact by the method ejbActivate.

After the client has obtained a session bean, it can access the bean instance via the remote or local object. The method calls are relayed by the EJB container to the bean instance. All client method calls are serialized by the EJB container. If a RuntimeException occurs in a method, then, as with stateless session beans, the bean instance is discarded by the EJB container.

A method can be executed in a transaction. Normally, the EJB container institutes a separate transaction for each method call and terminates it after the method executes (this depends on the configuration of the bean). It is also possible, however not usually recommended, to combine several method calls in a single transaction. This case is covered in the state Ready in TA. For technical reasons the EJB container is not able to passivate a bean instance if it is contained in a transaction. In order for the bean to be passivated, the transaction must time out. Transactions are covered in detail in Chapter 7.

The EJB container must also handle the case in which the connection to the client is broken. Here a simple heuristic is employed. If the client has not executed a method call within a certain period of time (Timeout), then the session is considered terminated. The EJB container deletes the bean instance, depending on the state, with ejbRemove or by deletion of the serialized bean instance.