Programming


Figure 6-8 provides an overview of the classes and interfaces of message-driven beans. The most conspicuous difference between session and entity beans is the lack of home and remote, and local home and local, interfaces.

click to expand
Figure 6-8: Interfaces of a message-driven bean.

Message-driven beans implement the interface javax.ejb.MessageDrivenBean and the interface java.jms.MessageListener (see the section in this chapter on receiving a message) either directly or indirectly. The class must be declared public. The class must have a parameterless constructor that is declared public. This is used by the EJB container to generate instances of a message-driven bean. The class is not permitted to implement the method finalize.

The methods of a message-driven bean can be divided into three categories:

  • state management;

  • identity management;

  • application logic.

The following sections describe the individual methods in these groups. A study of the programming examples will provide a rapid introduction to programming of these methods.

State Management

With message-driven beans there is only one method that informs a bean instance of an imminent state change, namely, the method setMessageDrivenContext. In the case of message-driven beans a state change is initiated exclusively by the container. The implementation of the method setMessageDrivenContext stores the passed context. This can later be used to communicate with the container. (In the subsection on the message-driven context we will discuss context more fully.) In this method the specification allows access to the environment of the message-driven bean only over JNDI. How an Enterprise Bean accesses its environment is discussed fully in Chapter 4. Immediately after a call to the method setMessageDrivenContext there follows a transition into the state Pooled Ready.

Identity Management

The methods for identity management form the second group of methods of a message-driven bean. They make possible the generation and deletion of message-driven bean identities. In contrast to those of session and entity beans, these methods are used exclusively by the EJB container. The client has no way to influence the generation and deletion of message-driven bean identitites. An instance of a message-driven bean has no identity in relation to the client. The EJB container uses the identity internally for managing the instances of a particular type of message-driven bean.

ejbCreate

With a call to ejbCreate the EJB container places an instance of a message-driven bean in the state Pooled Ready and uses it immediately for processing incoming messages. A message-driven bean must define precisely one method ejbCreate without parameters. Within this method the message-driven bean is permitted access to its environment only over JNDI and possibly access to a user transaction object via the message-driven context. Access to the environment via JNDI is described in Chapter 4. Working with transactions and the use of the interface javax.transaction.UserTransaction are described in Chapter 7.

ejbRemove

When the EJB container no longer needs a bean instance, it deletes it by a call to the ejbRemove method. This destroys the identity of the instance. It can no longer be used for processing messages. If the bean has reserved resources, these must be released with the call to this method. As with the method ejbCreate, the bean is allowed acess to its environment only via JNDI and perhaps to a UserTransaction object via the message-driven context.

Application Logic

The application logic of a message-driven bean can be implemented only in a method, namely, onMessage. It cannot be called by a client. It is always called by the EJB container when a message arrives over the channel of the message service allotted to the message-driven bean. The EJB container must ensure that the calls to this method are serialized. The implementation of this method does not need to be thread-secure. The channel (destination) of the message service associated with the message-driven bean is set in the deployment descriptor.

The method onMessage provides access to the bean's environment via JNDI, to the services that the container offers (database, Java Message Service, etc.), and to other Enterprise Beans. Chapter 4 describes how an Enterprise Bean accesses its environment via JNDI. There it is also explained how an Enterprise Bean can access services and resources of the EJB container. If a message-driven bean uses another Enterprise Bean, it is then in this respect just an ordinary Enterprise Bean client. The viewpoint of a client toward a session or entity bean is described in Chapters 4 and 5.

In the case of transactions that are run by the container, the bean can use the methods getRollbackOnly and setRollbackOnly of the interface MessageDrivenContext. With transactions that are run by the bean itself, it can use a UserTransaction object to which it has access via the message-driven context. Transactions and the use of objects of type javax.transaction.UserTransaction are described in Chapter 7. The specification prescribes that a message-driven bean is not permitted to use the acknowledgment mechanism of the JMS. If the message-driven bean uses container-managed transactions, then the receipt of a message is automatically confirmed with the transaction's commit by the EJB container. If the message-driven bean manages its own transactions, then the receipt of a message is not a part of the transaction. In this case the specification recommends setting the acknowledge mode to AUTO_ACKNOWLEDGE. This setting is carried out in the deployment descriptor. If the setting of the acknowledgment mechanism is lacking in the deployment descriptor, then the EJB container automatically makes the setting AUTO_ACKNOWLEDGE.

The method onMessage declares no exceptions, and it should throw no exceptions as well (this holds also for javax.ejb.EJBException). A normal JMS client that receives messages has just as little possibility of throwing exceptions in this method. If the message-driven bean throws an exception of type RuntimeException, then it is placed in the state nonexistent by the EJB container. It assumes that this instance is no longer capable of processing messages correctly.

The Message-Driven Context

With the MessageDrivenContext an instance of a message-driven bean is able to communicate with the EJB container. With message-driven beans this is necessary above all for the control of transactions. The context of a message-driven bean can be changed by the EJB container during the lifetime of an Enterprise Bean. The context is transmitted via the method setMessageDrivenContext of the interface javax.ejb.MessageDrivenBean. We shall now present briefly the methods of the message-driven context.

setRollbackOnly

This method aids in control of transactions (see Chapter 7). It is used by a bean instance to make it possible to cancel all the actions of a transaction in case of error. This method can be used only by message-driven beans that use transactions controlled by the container.

getRollbackOnly

The method getRollbackOnly is the read counterpart of the method setRollbackOnly. With this method it can be checked whether the current method call can still be successfully completed. Like setRollbackOnly, this method can be used only by message-driven beans that use container-managed transactions.

getUserTransaction

This method can be called only by message-driven beans that manage their own transactions. The return value of this method is an object of type javax.transactionUserTransaction from the Java transaction API (see Chapter 7).

getCallerPrincipal

This method is inherited by the message-driven context from the interface EJBContext. A message-driven bean is not permitted to call this method. Normally, this method makes it possible to determine the user that makes this method call. Since a message-driven bean cannot be directly addressed by a client, a call to this method makes no sense in any case.

isCallerInRole

The same considerations hold for this method as for the method getCallerPrincipal. This method would make it possible to determine the role of the user that is making the current method call.

getEJBHome

This method, too, is forbidden to a message-driven bean. It, too, is inherited from the interface EJBContext. This method permits access to an instance of the implementation of the bean's (local) home interface. Since a message-driven bean has no need for a (local) home interface, a call to this method makes little sense.

An attempt by a message-driven bean to call a forbidden method on the message-driven context is acknowledged with

 java.lang.IllegalStateException. 

The Client

Programming the client corresponds exactly to the programming of a normal JMS client. The programming of JMS clients was dealt with in the first section of this chapter.




Enterprise JavaBeans 2.1
Enterprise JavaBeans 2.1
ISBN: 1590590880
EAN: 2147483647
Year: 2006
Pages: 103

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