Messenger is a JMS (Java Message Service) framework which makes it very easy to use JMS in Web Service and Web Application environments.
Messenger implements session pooling (which can be quite hard to do with JMS) which makes JMS very easy to work with. Also Messenger hides much of the complexity of JMS behind a simple facade API, the Messenger interface.
In addition Messenger provides an XML deployment configuration file to avoid having to litter your code with complex deployment configuration details in your application code.
Messenger also provides a Messagelet Engine which is a JMS based container that can be deployed in any Servlet Engine to process JMS messages via MessageListeners, Message Driven Objects, Servlets or JSP.
Here is an example Messenger.xml deployment configuration file.
<?xml version="1.0" encoding="UTF-8"?> <manager> <!-- this example Messenger XML config file should work with J2EE SDK --> <messenger name="topic"> <jndi lookupName="TopicConnectionFactory"> <property> <name>com.sun.jms.internal.java.naming.factory.initial</name> <value>com.sun.enterprise.naming.SerialInitContextFactory</value> </property> </jndi> </messenger> <messenger name="queue"> <jndi lookupName="QueueConnectionFactory"> <property> <name>com.sun.jms.internal.java.naming.factory.initial</name> <value>com.sun.enterprise.naming.SerialInitContextFactory</value> </property> </jndi> </messenger> </manager>
It should work with the J2EE SDK to make 2 standard Messengers called topic and queue respectively.
So how would we use these 2 Messengers from Java code?
Here's some example code to send a message on a topic.
// get a Messenger and Destination Messenger messenger = MessengerManager.get( "topic" ); Destination destination = messenger.getDestination( "CHAT.NEWBIES" ); // now lets send a message TextMessage message = messenger.createTextMessage( "this is some text" ); messenger.send( destination, message );
Here's some code to receive a message on a queue, blocking until the message arrives.
// get a Messenger and Destination Messenger messenger = MessengerManager.get( "queue" ); Destination destination = messenger.getDestination( "REQUEST.BUILD" ); // now lets receive a message Message message = messenger.receive( destination );
Notice how the construction of individual Messenger objects can be hidden behind the MessengerManager in a similar way to tools like log4j.
Also notice that the Messenger API is a simple facade, no need for Topic and Queue specific coding as well as the use of MessageConsumer, MessageProducer, TopicPublisher, TopicSubscriber, QueueSender, QueueReceiver and the plethora of Connection and Session objects.
By default, Messenger will look for an XML document called Messenger.xml on the CLASSPATH as soon as a Messenger instance is looked up via the following code.
Messenger messenger = MessengerManager.get( "customer.orders" );
An alternative approach is to define the system property org.apache.commons.messenger to point to a URL of a Messenger deployment configuration document. For example
$ java -Dorg.apache.commons.messenger=http://localhost/config/Messenger.xml MyApplication
In servlet environments its often a good idea to explicitly configure the singleton MessengerManager in a Servlet initialisation method using servlet initialisation parameters. Here's an example
public class MyServlet extends HttpServlet { public void init() throws ServletException { // initialise the Messenger connections String url = getInitParameter( "messenger" ); if ( url != null ) { MessengerManager.configure( url ); } } }
The Messenger project provides a Messagelet Engine which is a JMS based Container which runs in any Servlet Engine such as Tomcat 4.0. The Messagelet Engine provides a simple framework for processing JMS messages in a variety of ways using either regular JMS MessageListeners, Message Driven Objects, Servlets or even JSP.
To deploy a Messagelet Container you need to add the ManagerServlet in a web application giving it an XML configuration file describing all the various JMS connections and an XML configuration file describing all the subscriptions.
Here are example connections and subscriptions XML configuration files. There now follows the section you need to add to your web.xml configuration file to deploy the Messagelet Manager Servlet.
<servlet> <servlet-name>managerServlet</servlet-name> <servlet-class>org.apache.commons.messagelet.ManagerServlet</servlet-class> <init-param> <param-name>connections</param-name> <param-value>/WEB-INF/Messenger.xml</param-value> </init-param> <init-param> <param-name>subscriptions</param-name> <param-value>/WEB-INF/subscriptions.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
Once you've done the above and the web application is started the Messagelet engine will subscribe to the various JMS subscriptions and then dispatch JMS messages to the various MessageListener objects, Servlets or JSP pages.
There are a variety of ways in which you can process JMS messages depending on your requirements.
There are some examples of an MDO, Servlet and Messagelet here or you can see example JSP here
In addition the Messagelet engine provides a Bridge mechanism which allows messages to be consumed from one destination and connection and sent to another destination, possibly using a different JMS connection and provider. This allows, for example, messages to be consumed on SpiritWave and sent to MQSeries, possibly applying some custom transformation along the way.
The Bridge mechanism is provided via the BridgeMDO and using the <bridge> element inside a subscription deployment descriptor.