FioranoMQ provides an Application Server neutral mechanism to integrate JMS with EJB. This document reviews in depth the issues that FioranoMQ has solved with this method of integration. Samples illustrating how JMS can be used for asynchronous invocation of EJB methods can be downloaded from JMS-EJB Sample Applications. This section explains how the power of EJB can be leveraged using asynchronous Java Messaging technology. This section also illustrates how FioranoMQ's implementation of JMS provides support for asynchronous EJB method invocation, as well as the limitations inherent in the EJB architecture for doing the same. It also contains an EJB JMS sample.
29.3.1 Asynchronous Method Invocation using Delegation Model
Using the services provided by FioranoMQ, it is possible for one EJB to asynchronously invoke methods on another Bean. FioranoMQ achieves this through a delegation model, where a request is passed on, or delegated to, another entity that handles the request and returns a response. This allows a given EJB (or a Client Application using EJB) to trigger methods on any other Bean. The delegator class is responsible for listening on a JMS Queue, marshalling the incoming JMS messages and invoking appropriate remote methods on the desired target Bean. The delegator class can be executed as either an Application Server specific startup class or as a standalone JMS Application. If the delegator class is assigned as one of the startup classes of the Application Server, then the Application Server is responsible for invoking this class in the JVM instance.
29.3.2 EJB JMS Sample Application
The example in the figure below illustrates how JMS can be used to invoke, asynchronously, methods on an EJB.
Figure1: Illustrating the Use of JMS for Asynchronous Method Invocation on EJBs
The sample and the JMS-EJB integration work as listed below:
- Client applications (referred to as Client EJB Stubs) publish a JMS message each time they want to invoke a method on a remote EJB
- All published JMS messages are received by a delegator application, which invokes the appropriate methods on the remote EJB using the Java reflection API.
- The JMS-EJB integration application has three components, each of which is discussed below:
- Event Generator: The Client application generating the requests to invoke the remote EJB methods
- Delegator: A FioranoMQ JMS application that reads the message and invokes each remote EJB method
- EJBs: The actual EJBs whose methods are invoked
29.3.3 Event Generator
The Event Generator publishes JMS Messages to a Queue (primaryqueue by default). Each message contains relevant information regarding the methods to be invoked in specific, remote, EJBs. The Client Application represents the Event Generator. In a real world example, the Event Generator might be a Shopping cart Bean that needs to asynchronously trigger the method of another Bean, dependent upon the User clicking checkout on an HTML page.
The file Publisher.java contains the Event Generator, which simulates an event that is used to invoke appropriate EJBs. The goal of the Generated Event is to invoke one of the three beans (Add, Delete or Update), once every two seconds. Since there are no limitations to the JMS Messages being published by EJB, the Event Generator, in effect, becomes an EJB. The only task of the Event Generator is to generate JMS messages that encapsulate the Add/Delete/Update events which are then invoked on a remote bean.
The JMS message (event) includes the following information:
- Name of the target EJB to be looked up.
- The API used to create instances of the EJB and arguments, if any.
- Name of the method to invoke in the target EJB and arguments, if any.
- The information above is required by the Delegator class to invoke the appropriate method asynchronously on the target bean.
29.3.4 Delegator
The Delegator represents a generalized application that is responsible for receiving events asynchronously and invoking appropriate methods on the target EJB. The JMS Application listens for messages on a queue (primaryqueue by default), de-marshals the messages and invokes the appropriate method in the target EJB. The Delegator class is a generalized class that uses reflection to invoke any remotely accessible method in the requested EJB. The class Subscriber.java represents the Delegator class. The JMS Application implements an asynchronous listener to listen in for messages that are published on the queue primaryQueue. The Delegator receives the JMS Messages that are published on the Queue and demarshalls the content of the JMS Message. It finally looks up and invokes appropriate methods on the EJB with appropriate parameters, using reflection. Optionally, this class can be placed in the startup class of an Application Server, thereby passing on the responsibilities of the Delegator to the Application Server.
29.3.5 Enterprise Java Beans
Three simple stateless session Beans (AddBean, UpdateBean and SessionBean) are used as the target EJBs. The method of the Beans is invoked by the Delegator (described in section 29.3.4 Delegator).
29.3.6 Limitations of Enterprise Java Beans
EJBs do not provide for asynchronous method invocation for the reasons given below:
- EJBs do not run as a daemon service. EJBs are server-side reusable components that can be put back into the available pool of the container when they time-out or when there are no more active references to the Bean.
- EJBs can be accessed only through a remote interface. An EJB cannot be made to receive a JMS Message asynchronously, since this result in the direct invocation of Bean methods. By definition, an EJB can only be accessed through its remote interface. The container of the EJB is responsible for managing and invoking all calls on the Bean. Since the EJB container manages all transactions and threads the safety operations of the Bean, direct access to the Bean method is restricted, as this can result in a potentially catastrophic operation. EJBs cannot be used to create a JMS message listener that asynchronously receives messages since this would invocation the Bean methods directly.