Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Distribute JavaBean Events Across Java Virtual Machines : Page 4

The JavaBean event model provides simple messaging, but it works only within a Java virtual machine (JVM). JMS allows you to send messages across a network to other JVMs, but it is quite complex. This article presents a quicker, simpler solution: transparently distributing JavaBean events over JMS.

The DistEvent Object
The Event Distributor uses an invocation handler to handle calls on each event interface proxy. It collects and wraps all the details of the method call, as outlined in the previous section, in a DistEvent object that it publishes using JMS.

In order for JMS to send this object between Java virtual machines and over the network, DistEvent must implement the java.io.Serializable interface. This interface simply identifies the implementing class as being serializable.

Calling Listeners
The Event Distributor implements a subscriber that uses JMS asynchronous message notification. When a message arrives, JMS calls the subscriber object's onEvent method. This is where the DistEvent object is extracted from the JMS message, as shown in Listing 7.

Listing 7. Handling a Remote Event
When the Event Distributor receives a JMS message, it must deliver the message to the correct event listener components. The following code calls the correct method on each listener for the applicable event interface:

protected void onEvent( DistEvent distEvent ) { try { // Deliver the event to each listener // of this event interface Vector listeners = (Vector) listenerMap.get( distEvent.interfaceName ); if ( listeners == null ) return; int count = listeners.size(); for ( int i = 0; i < count; i++ ) { EventListenerDist listener = (EventListenerDist)listeners.elementAt(i); deliverEvent( listener, distEvent ); } } catch ( Exception e ) { } } protected void deliverEvent(EventListenerDist listener, DistEvent distEvent) { try { // Create the arg type array from the args array // This array is used to get the called method int argCount = distEvent.argNames.length; Class[] argTypes = new Class[argCount]; for ( int p = 0; p < argCount; p++ ) argTypes[p] = distEvent.eventArgs[p].getClass(); Class listenerClass = listener.getClass(); Method eventMethod = listenerClass.getMethod( distEvent.eventMethod, argTypes ); // The following invokes the event method on // the actual event listener object eventMethod.invoke( listener, distEvent.eventArgs ); } catch ( Exception e ) { e.printStackTrace(); } }

When the Event Distributor receives a JMS message, it performs the following steps:

  1. It locates the correct event listeners. It uses the interface name as a key to a HashMap, where each HashMap bucket points to a Vector containing listener objects. If at least one listener for this event interface exists, the Event Distributor will return and traverse a Vector.
  2. For each listener object in the Vector, the Event Distributor calls its deliverEvent method to deliver the event (see Listing 7).
  3. The Event Distributor uses the DistEvent object to extract the method's arguments. It then creates an array of Class objects and then populates it with each argument's type by calling getClass on each argument object. The Event Distributor uses this array, along with the given method name, to get a reference to the correct Method object.
  4. To invoke the event method on the actual listener object, it calls invoke on the Method object.

Figure 7 illustrates the entire process of sending and receiving a remote event.

Figure 7: Sending and Receiving a Remote Event

Simple and Quick Inter-JVM Communication
Although in some cases you will need to use the JMS API directly, the Event Distributor makes inter-JVM communication simple and quick. Simply put, the Event Distributor is a wrapper class that allows your code to use JMS through the JavaBean event model. As an added benefit, it provides a consistent remote messaging pattern within your code, which makes it easier to maintain and less prone to bugs.

Eric Bruno is a development analyst with Reuters in New York. He has worked extensively with Java, C++, and COM through the years, developing real-time trading systems, news systems, and financial applications. Reach him by e-mail at eric_j_bruno@yahoo.com.
Comment and Contribute






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