ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

XML Messaging Using JBoss XML Messaging Using JBoss

by Benoit Aumars
10/13/2004

It's common practice to share data using FTP, but an increasingly popular alternative is to use a messaging service. As always, each approach has its own pros and cons, depending on the nature of "what to share," how easy it is to implement the technology, the need to use an asynchronous process, etc.

In this article, I will focus on data sharing, with the common producer-consumer model, using open source software such as:

  • JBoss: A popular open source application server
  • Quartz: A job scheduling system
  • Hibernate: An object/relational persistence and query service for Java
  • Castor: A Java-XML data-binding framework

The interactions between them are managed by Java Management Extensions (JMX). Please refer to their respective home pages if you are unfamiliar with these frameworks.

As for the Java Messaging Service (JMS) provider, you can choose either WebSphere MQ or JBossMQ. This is fully configurable in the jboss-service.xml file provided. By using JMS, your application becomes "loosely coupled." Some benefits of using it are:

  • Messages can be prioritized.
  • Messages can be delivered synchronously or asynchronously.
  • Messages are guaranteed to be delivered.

This article is about how to use the set of open source tools listed above, not about why I choose them, nor why I need them. There are obviously a million and one different ways to deal with the producer-consumer model. The idea behind using JMX is to have a more flexible "federated" approach, so that different functions are handled by different processes.

Case Study

Consider the following hypothetical scenario. We want to share two different kinds of data, coming from two different applications and two different data sources. One application (AppSource1) uses an Oracle database and needs to share a subset of its business contact data. Another application (AppSource2) uses a Sybase database and needs to share a subset its currency data.

The data is shared at specific times:

  • From 08:00 to 18:00, daily, for the contact data
  • Every minute, daily, for the currency data.

The contact data, persisted in an interface table named IProducerContact, is managed and controlled by the application AppSource1. The currency data is persisted in an interface table, IProducerCcy, by the application AppSource2. Both AppSource1 and AppSource2 are the producers.

The producers extract the data from the interface tables IProducerContact and IProducerCcy and then send the data, in an XML format, to a JMS server. The consumer processes each incoming message, which then populates two interface tables, IConsumerContact and IConsumerCcy. Once in the interface tables, AppTarget is responsible for extracting the data from them into the master database.

Figure 1 below depicts this scenario:

Figure1
Figure 1. Flow of messages

JMX in JBoss

JMX is an optional package for J2SE that provides a standard set of interfaces and enables you to add management capabilities to your applications. It allows developers to write more modular and loosely coupled system components and reduce the complexity of large, interoperating systems.

The core component of JMX is the managed bean, or MBean. A standard MBean is a Java class that implements an interface, which has the following characteristics:

  • Constructor
  • Attributes
  • Operations

An example in JBoss is shown below:

public class ProducerManager extends ServiceMBeanSupport 
             implements ProducerManagerMBean {
   ...
   // Constructor
   // define your getter/setter method
   // define your operations
    
   public void startService() throws Exception {
       ...
   }
    
   public void stopService() throws Exception {
       ...
   }
}

where the ProducerManagerMBean interface is:

public interface ProducerManagerMBean extends ServiceMBean {
   ...
   // define your getter/setter method
   // define your "invoked" operation, if any
}

Then, you need to define an XML file service, i.e. jboss-service.xml:

<?xml version="1.0" encoding="UTF-8"?>
<server>
  <mbean code="example.jmx.ProducerManager" 
         name="nusa:service=ProducerManager">
    <attribute name="Oracle">false
    </attribute>
  </mbean>
</server>

Once you have defined your MBean and the XML file service, then you can package them into a .sar file. This service archive file is ready to be deployed into JBoss server.

Let's find out what happens when you deploy an MBean. The sequence of an MBean initialization is in this order:

  • Call the constructor of the MBean.
  • Call the setter methods.
  • Call the startService() method.

When you delete or override the .sar file--or stop the JBoss server, but you may not want to do this--the stopService() method is called. This is the appropriate place to do clean-up operations, like closing all open connections or sessions.

You can define a dependency between one MBean with another MBean by using the depends tag:

<?xml version="1.0" encoding="UTF-8"?>
<server>
  <mbean code="example.jmx.ProducerManager" 
         name="nusa:service=ProducerManager">
    <attribute name="Oracle">false
    </attribute>
    <depends optional-attribute-name="MOMManager">
        nusa:service=MOMManager
    </depends>
    <depends optional-attribute-name="DBManager">
        nusa:service=DBManager
    </depends>
  </mbean>
</server>

In this example, the ProducerManager MBean depends on the MOMManager MBean and DBManager MBean.

Again, what happens if you deploy a .sar file with the above file service? Here is the sequence:

  • Call the ProducerManager() constructor.
  • Call the setter method in ProducerManger (setOracle(), in this instance).
  • Call the MOMManager() constructor.
  • Call the setter method in MOMManager.
  • Call the DBManager() constructor.
  • Call the setter method in DBManager.
  • Call the startService() method in DBManager.
  • Call the startService() method in MOMManager.
  • Call the startService() method in ProducerManger.

When you delete or override that .sar file, here is the sequence:

  • Call the stopService() method in ProcedureManager.
  • Call the stopService() method in MOMManager.
  • Call the stopService() method in DBManager.

Note: Take a look at the order. When you have a dependency, the order is important.

The next thing that we need to know is how to call a method in an MBean from another MBean. Given the file service mentioned above, how the MOMManager MBean call a method in DBManager MBean? The key is to use the invoke() method, such as:

instanceofmbeanserver.invoke ( yourObjectName,
                               yourMethod,
                               params,
                               signature );

The following code is taken from the provided source:

public void processXML(String xmlMsg ,String msgType) 
        throws Exception {

  log.info ( "=== XMLConsumerCcyMDB.processXML() : 
              invoke XMLConsumer service ");
  Object[] params    = new Object[] { xmlMsg 
                                     ,msgType };
  String[] signature = new String[] { "java.lang.String" 
                                     ,"java.lang.String" };
  server.invoke(mbean, "processXML", params, signature);
}

The javax.management.MBeanServer.invoke() method is powerful and can invoke methods of any given complexity by providing details about the method parameter signature and supplying the parameter values.

Note: The yourMethod() method must be defined in your MBean interface and implemented in your MBean class.

Pages: 1, 2, 3, 4

Next Pagearrow