Browse DevX
Sign up for e-mail newsletters from DevX


JMS Enables Concurrent Processing in EJB : Page 2

JMS provides an elegant solution for overcoming the restrictions you face when developing concurrent applications with EJB. Learn how its asynchronous model and its support for the MessageDrivenBean can enable a client to use EJB asynchronously.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

JMS Design for Concurrency
To call EJB concurrently, you can design a set of classes that a client uses to divide a task into subtasks. Then the client can send each subtask asynchronously as a message to JMS Queue for processing by the MDB. The MDB can call the SessionBean to process the subtask and then to send an acknowledgement back to the client.

The following section discusses both the client-side and server-side designs for using EJBs concurrently.

Client-side Design
On the client side, you need two JMS Queues: one to send subtasks and the other to receive acknowledgement for the processed subtasks. Figure 1 shows the class diagram for client-side processing logic.

Figure 1: Class Diagram for Client-side Processing Logic

The TaskManager (see Listing 1) interface has common behavior that must be implemented by any class that provides implementation for subtask management. The JMSTaskManager (see Listing 2) implements the TaskManager and provides JMS implementation for calling the EJB concurrently. For example, you could use the TaskManager to implement Web services for managing and processing subtasks.

You use three methods collectively to perform subtask management for the clients:

  1. sendSubTasks() sends a collection of subtasks to the EJB for processing.
  2. listenForAcknowledgement() listens for the acknowledgement messages for all the subtasks sent to MDB.
  3. waitForAcknowledgement() makes the client wait for the acknowledgement to come from MDB.

As explained previously, the JMSTaskManager class (see Listing 2) provides JMS implementation for the TaskManager. The default constructor initializes totalMessagesSent and totalMessagesReceived variables, which hold messages (subtasks) sent and acknowledgements received, respectively, for the processed subtasks. It also constructs the InitialContext for JNDI lookup and calls setupQueue(), which constructs JMS Queue objects to perform point-to-point communication between JMSTaskManager and the MDB.

The sendSubTasks() method takes a collection of subtasks, adds each subtask into JMS message, and sends it to the JMS Server. The createMessage() method is an abstract of this class that takes QueueSession and a subtask and then returns a message for sendSubTasks() to send. Since createMessage() is an abstract, subclasses can construct all types of JMS messages, such as BytesMessage, MapMessage, ObjectMessage, StreamMessage, TextMessage, etc. The constructed message is used to set the JMS Reply Queue on the server side. Once the MDB processes a subtask, it sends an acknowledgement message back to JMSTaskManager (using the Reply Queue). The name of the Reply Queue is obtained from getReceiveQueueName(), which is an abstract method in this class. Finally, the QueueSender object is used to send the messages to the JMS Server.

The sendMessage() is provided for convenience. If, for any reason, a client wants to send only one subtask, this method can be used for that.

The onMessage() method is automatically executed when the MDB sends an acknowledgement message to the Reply Queue and increments the totalMessageReceived counter by one.

The listenForAcknowledgement() method uses getReceiveQueueName() to create a Queue to receive the acknowledgements from the MDB. The JMSTaskManager implements the MessageListener interface so that it can listen for acknowledgements from MDB. The QueueSession is used to create the QueueReceiver, which is used to set the MessageListener object to get acknowledgements from MDB.

You can create two types of QueueReceivers, one using MessageSelector and one without using it. If the subclass of JMSTaskManager provides a MessageSelector, you use it to construct the QueueReceiver. The JMSTaskManager uses the date as the MessageSelector to filter the acknowledgement messages from the MDB. This feature allows more than one client to use the JMSMessageManager to send subtasks concurrently to MDB (see Figure 17). In this scenario, each client uses its own date as the message Selector so that JMSTaskManager receives acknowledgement messages for its date.

The waitForAcknowledgement() method waits in a loop until the JMSTaskManager receives all the acknowledgement messages from MDB.

Server-side Design
This section discusses what the server-side classes require to process subtasks using JMS Messages. On the server side, you need to design a MDB so that when the client sends a message, the JMS Server notifies the MDB to process that message.

Like all other MDB classes, the SubtaskMessageBean class (see Listing 3) implements MessageDrivenBean and MessageListener interfaces (see Figure 2).

Figure 2: QueueConstants Interface Holds Various Queue Constants

The JMS Server calls the onMessage() method when the JMSTaskManager sends a message with the subtask embedded in it. Typically, this method calls a SessionBean to process the Subtask. For simplicity, in this example it prints the date and the subtask passed by the client. At the end, it calls the sendAcknowledgement() method to send the acknowledgement message to the client.

The sendAcknowledgement() method receives the Reply Queue that the JMSTaskManager sends and uses it to send the text acknowledgement message back to it. It uses the client-passed date to set the message Selector by calling the setStringProperty in the TextMessage. This helps the client accept the acknowledgement messages based on the date it passed to the SubtaskMessageBean.

The QueueConstants interface (see Listing 4) holds various Queue constants that both the client-side and server-side Java classes use.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date