5.2 How the Container Manages Session Beans at Runtime

This section explains how the EJB container manages the session bean at runtime. We use object interaction diagrams (OIDs) to illustrate the interactions among the client, the distributed objects implemented by the container, and the instances of the session bean class. Some of the examples that follow use the remote interface and the remote home interface to illustrate the interactions. Keep in mind that similar interactions happen for local interfaces, too, except that local objects have no distributed objects and hence no network activity.

5.2.1 EJB Home Interface Lookup

Recall that a client program uses the following code to locate a session bean's home interface:

 ... Context ictx = new InitialContext(); Object h = ictx.lookup("java:comp/env/ejb/PayrollEJB"); PayrollHome payrollHome = (payrollHome)    PortableRemoteObject.narrow(h, PayrollHome.class); ... 

This code performs a JNDI lookup operation and casts the found object to the PayrollHome home interface type.

The OID in Figure 5.2 illustrates the EJB container actions that occur "under the covers" when the client initiates a lookup operation.

  1. The client application creates an instance of the InitialContext class, which, because it is part of the JNDI, is defined in the javax.naming package.

  2. The client invokes the lookup operation and passes to the method the string java:comp/env/ejb/PayrollEJB as the parameter.

  3. The InitialContext object delegates the lookup operation to a ContextImpl class provided by the EJB container. What causes this to happen? At deployment, the deployer must configure the JNDI namespace for the client application. In our example, the deployer configured the JNDI InitialContext object to delegate all JNDI operations for names beginning with the prefix java: to a ContextImpl class provided by the EJB container. If the client resides on a different machine from the container, this operation may result in a network trip to the container.

Figure 5.2. Home Interface Lookup OID

graphics/05fig02.gif

The container returns the PayrollHomeRMI home object to the client. The client program obtains a reference to the RMI stub for the PayrollHomeRMI object. The stub implements the PayrollHome interface, which allows the client to subsequently invoke the methods defined in the PayrollHome interface on the stub.

Note that the EJB specification requires the client to convert the result of the lookup operation by using the PortableRemoteObject.narrow method. The reason is that the home object is a remote object. If the client uses a simple Java cast to convert the result of the lookup operation, the cast operation could fail with some EJB container implementations.

5.2.2 Session Object Creation

Let's look at what happens when the client program invokes the create method on the session bean home object with the following line of code:

 payroll = payrollHome.create(); 

The OID diagram (Figure 5.3) illustrates how the container performs this operation.

  1. The client program invokes the create operation on PayrollHome, which is the RMI stub for the PayrollHomeRMI object. The stub forwards the request over RMI-IIOP to the implementation of the PayrollHomeRMI object residing in the EJB container. (The figure does not show the forwarding operation.)

  2. The implementation of the PayrollHomeRMI object creates a new PayrollRMI object. Note that this is a distributed RMI-IIOP object, not a simple Java object.

  3. The implementation of the PayrollHomeRMI object creates a SessionContext object. The container uses the SessionContext object internally to manage information about the associated PayrollBean instance.

  4. The implementation of the PayrollHomeRMI object also creates an instance of the PayrollBean class, using the public constructor, which takes no arguments.

  5. The implementation of the PayrollHomeRMI object then invokes the setSessionContext method on the PayrollBean instance to pass the SessionContext object to the instance. The instance may save the reference to the SessionContext object and use it later to communicate with the container.

  6. The implementation of the PayrollHomeRMI object invokes the matching ejbCreate method on the PayrollBean instance. The parameters to the ejbCreate method are the parameters of the client-invoked create method. The session bean instance may perform the initialization of its conversational state for stateful session beans in the ejbCreate method.

Figure 5.3. Create a Session Object OID

graphics/05fig03.gif

When these operations are complete, the container returns a remote object reference of the PayrollRMI distributed object to the client program. The stub implements the Payroll remote interface.

The create operation does not run in the client's transaction context. Therefore, if a client's transaction rolls back after the client creates a session object, the container does not remove the new session object, such as PayrollRMI, in our example; nor does it undo the work of the ejbCreate method. The client can use the session object.

5.2.3 Business Method Invocation

This section discusses how the container manages the execution of the client-invoked business methods. This is probably the heart of an EJB application.

The OID for the business method invocations is the most complex of the OIDs. It is important to keep in mind that these diagrams illustrate what the container is doing for the application. Because the container is responsible for these actions, the application developer's job is greatly simplified. To put it another way, the application developer merely invokes one business method, but the container must manage this with approximately 14 separate operations. Without the EJB container and environment, the application developer would have to write the code for these 14 operations, a far-from-easy task.

In addition, the case we are examining here is rather simple. Two session beans use two databases in a transaction. Although one session bean does call another enterprise bean within a transaction, the session bean does not import a client's transactions; nor does it use the SessionSynchronization interface. Many real situations are much more complex, involving multiple databases, other enterprise beans, multiple transactions, transaction synchronization, and so forth. In these cases, the container's job is even more complex and involves many more steps.

For our example, let's consider the case when the client, the EnrollmentWeb application, invokes the following business method on the Enrollment object:

 enrollment.commitSelections(selection); 

The OID diagram in Figure 5.4 illustrates the sequence of actions the container takes.

1. The client invokes the commitSelections business operation on the EnrollmentLocalObject instance.

2. The container initiates a new transaction. This happens because the bean developer specified the EnrollmentEJB session bean to be a bean with container-managed transaction demarcation and assigned the Requires transaction attribute to the commitSelections method. When a bean uses container-managed transaction demarcation, the container evaluates the bean's transaction attribute and determines how to handle the transaction demarcation. If a container-managed bean has the Requires transaction attribute, the container initiates a new transaction if the client is not already participating in a transaction. Note that if the client is already participating in a transaction, the client's invocation of the EnrollmentLocalObject object propagates the client's transaction to the container, and the container performs the work done by the session bean in the client's current transaction. See Chapter 10, Understanding Transactions, for more information. The container also checks whether the client is allowed to invoke the business method. If the client is not allowed to invoke the business method, the container throws RemoteException to the client. See Chapter 11, Managing Security, for information on security management.

3. The EnrollmentLocalObject object delegates the object invocation to the EnrollmentBean instance.

4. The EnrollmentBean instance the DBUpdateBenefits command bean used by EnrollmentBean performs a database operation to update the record in the Selections table in BenefitsDatabase.

5. The DBMS that stores BenefitsDatabase enlists itself with the transaction started in step 2. This is to ensure that the update to the Selections table is included as part of the transaction.

6. The EnrollmentBean instance through the DeductionUpdateBean command bean invokes the PayrollRMI session object via its RMI stub. The container propagates the transaction with the invocation to the PayrollRMI object.

7. The PayrollRMI object delegates the object invocation to the PayrollBean instance.

8. The PayrollBean instance updates the record in the Paychecks table in PayrollDatabase.

9. The DBMS that stores PayrollDatabase enlists itself with the transaction to ensure that the update to the Paychecks table is included as part of the transaction.

10. Before sending a reply to the client, the EnrollmentLocalObject object commits the transaction.

11. 14. The transaction manager coordinates the two-phase commit protocol across the two databases enlisted in the transaction.

Figure 5.4. Business Method Invocation OID

graphics/05fig04.gif

After the transaction manager commits the transaction, the EnrollmentLocalObject object sends the reply to the client. If the commit fails for any reason, the EnrollmentLocalObject object throws javax.ejb.EJBException to the client.

5.2.4 Session Bean Passivation and Activation

Let's assume that the user invoked a business method, such as the getMedicalOptions method, and then decided to interrupt the session with the EnrollmentWeb application. For example, the user starts the enrollment process, gets to the page displaying the available medical options, and then, realizing that it is time to go to lunch, locks the workstation screen, leaving the application where it is to resume it later. Shortly thereafter, the container detects that the Enrollment session object recall that the Enrollment session bean is stateful has been idle for a while. At that point, the container may decide to reclaim the memory resources by passivating the session object.

The OID diagram in Figure 5.5 illustrates the actions that the container takes to passivate the session object.

  1. The client invokes the getMedicalOptions business operation on EnrollmentLocalObject.

  2. The EnrollmentLocalObject object delegates the object invocation to the EnrollmentBean instance. At this point, the user leaves for lunch.

  3. The container detects that the client has not invoked a method on the session bean object for a while. If the container needs to reclaim the resources held by the session bean object, the container may choose to passivate the session bean object. The container invokes the ejbPassivate method on the EnrollmentBean instance. The ejbPassivate method gives the instance a chance to prepare its conversational state for passivation.

  4. The container saves the serialized instance of EnrollmentBean's state to secondary storage.

Figure 5.5. Passivation OID

graphics/05fig05.gif

Later, when the user comes back from lunch and resumes the session with the EnrollmentWeb application, the container activates the passivated object. It does this by taking the actions illustrated in Figure 5.6.

  1. The user returns from lunch and resumes the EnrollmentWeb application from the point at which the getMedicalOptions business operation on the EnrollmentLocalObject object was invoked. Now the user submits the form that results in the invocation of the setMedicalOption method on the session object.

  2. The EnrollmentLocalObject object tells the container this is an internal communication within the container to activate the object invocation and the state of the EnrollmentBean instance.

  3. The container loads into main memory the serialized instance of EnrollmentBean that it had previously stored in secondary storage.

  4. The container invokes the ejbActivate method on the EnrollmentBean instance, which at this point has been notified that it has been activated and can perform whatever operations are necessary to transfer itself to a state in which it can accept the invocation of a business method.

  5. The EnrollmentLocalObject object delegates the setMedicalOption object invocation to the EnrollmentBean instance.

Figure 5.6. Activation OID

graphics/05fig06.gif

5.2.5 Session Object Removal

The client invokes the remove method on the EnrollmentLocalObject object to remove the session bean instance. This is shown in the following code segment:

 enrollment.remove(); 

The client call to the remove method causes the container to invoke the following sequence of actions, as illustrated in Figure 5.7.

  1. The client invokes the remove operation on the EnrollmentLocalObject object that implements the Enrollment interface.

  2. The EnrollmentLocalObject object invokes the ejbRemove method in the EnrollmentBean instance to give the instance a chance to release the resources held in its conversational state. The JVM will eventually garbage collect the EnrollmentBean instance and all objects reachable from the instance.

  3. The EnrollmentLocalObject object removes itself. At that point, a client is no longer able to use the EnrollmentLocalObject object.

Figure 5.7. Session Bean Removal OID

graphics/05fig07.gif

If a client attempts to invoke a business method on a local session object after the object has been removed, the client receives javax.ejb.NoSuchObjectLocalException. (For remote objects, the client receives java.rmi.NoSuchObjectException.)

A client cannot remove a session object while the object is participating in a transaction. That is, the remove method cannot be called when the object is participating in a transaction; this throws javax.ejb.RemoveException to the client. For session objects having a remote interface, a client may also remove the session object, using the EJBHome.remove(Handle handle) method. Handles are discussed in Chapter 4.

The container has the option of invoking the ejbRemove method on an instance after the life of the session bean instance has expired, even without a prior remove method call from the client. See Section 5.2.6, Session Bean Timeout, which follows.

Finally, the remove operation does not run in the client's transaction context. Therefore, if a client's transaction rolls back after the client removed a session object, the container does not restore the removed session object, such as EnrollmentLocalObject in our example; nor does it undo the work of the ejbRemove method.

5.2.6 Session Bean Timeout

In some cases, a client may create a session object but then never call the remove method on this object. To handle these occurrences, the container typically uses a timeout mechanism to automatically remove session objects that are no longer used by clients. The deployer usually sets the timeout.

The container must be able to remove a session bean without waiting for the remove method invocation, because it needs, eventually, to deallocate the resources that it allocated for the session object, such as the space on secondary storage, to store the serialized image of the session bean instance. Essentially, if a client has not invoked the session object for a specified period of time, the container implicitly removes the session object. Keep in mind, however, that a session bean timeout never occurs while a session object is in a transaction.

When it removes the session object because of the timeout, the container may or may not choose to call the ejbRemove method on the session bean instance. The state of the session object determines whether the container invokes the ejbRemove method. If a session object is not in the "passive" state, the container invokes the ejbRemove method. If the session object has been passivated by the container, the container may simply reclaim the secondary storage allocated for the session object and not call the ejbRemove method. Therefore, the developer must design the application to tolerate the case in which the ejbRemove method is not called when a session object is removed.



Applying Enterprise Javabeans
Applying Enterprise JavaBeans(TM): Component-Based Development for the J2EE(TM) Platform
ISBN: 0201702673
EAN: 2147483647
Year: 2003
Pages: 110

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net