Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Initial doc - before review
Wiki Markup
{scrollbar}

Anchor
top
top

Enterprise messaging has become an increasingly important component of loosely coupled, reliable enterprise frameworks. This is due in large part to the proliferation of enterprise applications and disparate enterprise resources, and the increasing need to integrate these applications into cohesive systems. Over the years Messaging and Message Oriented Middleware (MOM) has provided this integration propritery waymanner. Introduction of Java Messaging Service (JMS) as a standard has , eliminated many of the disadvantages in propritery MOM based products. In addition to that Message Driven Beans (MDBs) introduced with Enterprise Java Beans 2.0 have served to get the best out of existing investments in J2EE application servers. Most of the J2EE application servers in modern era are acting as a MOM with a whole lot of value added services to JMS. As a J2EE 1.4 certified application server, Apache Geronimo comes in to the party with support of JMS integrating with one of the best breed open source messaging frameworks ActiveMQ. This article will guide you a way to use JMS/MDBs for in your enterprise application scenario in both as a locally and remotely reffered enviroments with Geronimo and ActiveMQ.

The company reffered in this sample application sales sells one specific item in both retail and whole sale markets. All the placed orders in the application has to be autorized by a company sales employee before delevering goods to the customer. To the whole sale market, company has placed their agents all over the country. They send their orders as a bunch at once which is called as a consignment. End users place their orders using company web site while agents send their consignments with a special software insalled in their premises. All the cosignments must be approved by the comany GM before it is handed over to a sales employee. This is a typical application to use JMS /MDBs as a solution because both cosignment and order requests are processed in asynchronous manner.

After reading this article you should be able to define Message Queues and their Connection Factories in Geronimo/ActiveMQ enviroment, send and recieve messages them using different kinds of client applications (including a MDB) in your Enterprise Application with ease.

...

Geronimo server comes with a JMS server and application components that can access JMS resources like connection factories, topics and queues from it. This JMS server also known as message broker too. Default The default message broker supports by Geronimo is ActiveMQ, usually does not need to be changed since it is a mature and feature-rich JMS serverproduct. This implementations uses inbuilt Derby database for the message persistent features.

ActiveMQ supports a large variety of transports (such as TCP, SSL, UDP, multicast, intra-JVM, and NIO) and client interactions (such as push, pull, and publish/subscribe). In Geronimo enviroment context ActiveMQ supports MDBs, which are EJBs that consume JMS messages. It allows enterprise application JMS applications to take J2EE specific features from Geronimo . Application and application components such as JSPs, Servlets or EJBs utilizing JMS must access message broker through a library that implements the JMS API. This API . Geronimo has been implemented this JMS API in an abstract layer to support any JMS provider. Geronimo It has achieved this this feature using by supporting J2EE Connector (JCA) specification. The JCA 1.5 specification details the contracts required between the application server (Geronimo) and the driver supplied by ActiveMQ (resource adapter). Applications deployed in the Geronimo access ActiveMQ message broker only through this resource adapter(RA).

...

Order processing application has two defined Queues message queues as to recieve orders and consignments. Order requests can be generated and send by the Order Sender web application. When order requests are reached recieved to the order queue, the Order recv a MDB will be triggered. Those order requests are saved in the server repository for the later authorization It will carry out the next level of order request processing by saving those requests in to a server repository. Those saved order requests will be processed by a company employee.

Compnay's sales agents are using the Consignment Sender application to send consignment (collection of orders) requests from their locations. First they will prepare consignments consignment as an XML filesfile, then it will be given it to that applicationpassed as an application parameter. Consignment Sender application will read the content of the consignment an XML file (with a consignmet request) and send it to the Consignment consignment queue. Senior General manager in the company uses Consignment Reciever application to find out the consignment requests. When a consignment request reached recieved to the Consignment queue, Consignment Reciever listener application will download those requests to the responsible manager's computer. Then he will authorize it and handed it over to a sales emplyee for further processing.

Following figure gives Following figure gives the overall architecture of the order processing application.

...

  • org.apache.geronimo.samples.order.client
    • ConsignmentReciever - Listening on recieving of consignment requests to a defined queue.
    • ConsignmentSender - Send consignment requests to their queue.
  • org.apache.geronimo.samples.order.ejb
    • OrderRecvMDB - Listening A MDB that listens on recieving of order requests to a defined queue.
  • org.apache.geronimo.samples.order.util
    • PropertyLoader - Loads configuration properties to application.
  • org.apache.geronimo.samples.order.web
    • OrderSenderServlet - Creates order requests based on the user input and send them to respective queue.

Finally core of the order placement application will be deployed as an EAR to the application server. Overview of the contents of EAR is given in the following.

...

Code Block
xml
xml
borderStylesolid
titlejms-resource-plan.xml
<?xml version="1.0" encoding="UTF-8"?>
<connector xmlns="http://geronimo.apache.org/xml/ns/j2ee/connector-1.1">
    <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1">
        <dep:moduleId>
            <dep:groupId>samples</dep:groupId>
            <dep:artifactId>jms-resources</dep:artifactId>
            <dep:version>1.0</dep:version>
            <dep:type>rar</dep:type>
        </dep:moduleId>
        <dep:dependencies>
            <dep:dependency>
                <dep:groupId>geronimo</dep:groupId>
                <dep:artifactId>activemq-broker</dep:artifactId>
                <dep:type>car</dep:type>
            </dep:dependency>
        </dep:dependencies>
    </dep:environment>
    <resourceadapter>
        <resourceadapter-instance>
            <resourceadapter-name>CommonConnectionFactory</resourceadapter-name>
            <config-property-setting name="Password">geronimo</config-property-setting>
            <config-property-setting name="UserName">geronimo</config-property-setting>
            <nam:workmanager xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.1">
                <nam:gbean-link>DefaultWorkManager</nam:gbean-link>
            </nam:workmanager>
        </resourceadapter-instance>
        <outbound-resourceadapter>
            <connection-definition>
                <connectionfactory-interface>javax.jms.QueueConnectionFactory</connectionfactory-interface>
                <connectiondefinition-instance>
                    <name>CommonConnectionFactory</name>
                    <connectionmanager>
                        <xa-transaction>
                            <transaction-caching/>
                        </xa-transaction>
                        <single-pool>
                            <match-one/>
                        </single-pool>
                    </connectionmanager>
                </connectiondefinition-instance>
            </connection-definition>
        </outbound-resourceadapter>
    </resourceadapter>
    <adminobject>
        <adminobject-interface>javax.jms.Queue</adminobject-interface>
        <adminobject-class>org.activemq.message.ActiveMQQueue</adminobject-class>
        <adminobject-instance>
            <message-destination-name>OrderQueue</message-destination-name>
            <config-property-setting name="PhysicalName">OrderQueue</config-property-setting>
        </adminobject-instance>
		<adminobject-instance>
            <message-destination-name>ConsignmentQueue</message-destination-name>
            <config-property-setting name="PhysicalName">ConsignmentQueue</config-property-setting>
        </adminobject-instance>
    </adminobject>
    <adminobject>
        <adminobject-interface>javax.jms.Topic</adminobject-interface>
        <adminobject-class>org.activemq.message.ActiveMQTopic</adminobject-class>
    </adminobject>
</connector>

Corresponding In this application there is a MDB that will listen on OrderQueue. openejb-jar.xml defines Geronimo specific features of MDBsthat MDB. It links OrderRecv MDB with OrderQueue via CommonConnectionFactory.

...

Code Block
xml
xml
borderStylesolid
titleapplication.xml
<?xml version="1.0" encoding="UTF-8"?>
<application 
       xmlns="http://java.sun.com/xml/ns/j2ee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
       http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"
       version="1.4">
    <module>
        <ejb>OrderEjb.jar</ejb>
    </module> 
	<module>
		<web>
			<web-uri>OrderWeb.war</web-uri>
			<context-root>/Order</context-root>
		</web>
	</module>
</application>

Order Processing Web application of the Order Processing system sends messages to the Order Queue. OrderSenderServlet will handle the relevant order request generation and sending. web.xml of the archive has the relevant configurations for the both queue connection factory and the queue, which is essential to refer resources in a local enviroment.

...

Note

Please note this web application supports Servlet 2.4 specification. These Some of the cofigurations in other versions (2.3) are bit different than given in the above web.xml.

geronimo-web.xml will act as the a mediator between defined JMS resources in the application server and the web.xml. It links both parties giving relavant information to the connection factory and the queue.

Code Block
xml
xml
borderStylesolid
titlegeronimo-web.xml
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1" xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.1">
  <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1">
    <dep:moduleId>
      <dep:groupId>samples</dep:groupId>
      <dep:artifactId>OrderWeb</dep:artifactId>
      <dep:version>1.0</dep:version>
      <dep:type>car</dep:type>
    </dep:moduleId>
    <dep:dependencies>
		<dep:dependency>
			<dep:groupId>geronimo</dep:groupId>
			<dep:artifactId>activemq-broker</dep:artifactId>
			<dep:version>1.1</dep:version>
			<dep:type>car</dep:type>
        </dep:dependency>
		<dep:dependency>
            <dep:groupId>samples</dep:groupId>
            <dep:artifactId>jms-resources</dep:artifactId>
            <dep:version>1.0</dep:version>
            <dep:type>rar</dep:type>
        </dep:dependency>		
	</dep:dependencies>		
    <dep:hidden-classes/>
    <dep:non-overridable-classes/>
  </dep:environment>

  <context-root>/Order</context-root> 
  <resource-ref>
    <ref-name>jms/CommonConnectionFactory</ref-name>
    <resource-link>CommonConnectionFactory</resource-link>
  </resource-ref>
	
  <resource-env-ref>
	   <ref-name>jms/OrderQueue</ref-name>
	   <admin-object-link>OrderQueue</admin-object-link>
  </resource-env-ref> 
</web-app>

The whole order processing application will load external resource using order_mgmt.properties. To send order requests to the queue, web application will use the Order Sender Properties in the given filenext important part of this sample application is how to send messages from out side the application server context. Consignment sender will handle it for the application as given below.

Code Block
xmljavaxml
java
borderStylesolid
titleorder_mgmtConsignmentSender.propertiesjava
###########################################################

## Order Sender(Web Application) Properties
#  Connection Factory Name. 
jms.connection=java:comp/env/jms/CommonConnectionFactory
# Queue Name.
jms.queue=java:comp/env/jms/OrderQueue

###########################################################

## Order Reciever(EJB Application) Properties
#  Change a directory in server to store order requests. 
order.repo=/home/lsf/Lasantha/Temp/order

###########################################################

## Consignment Sender Properties
#  Queue connection factory type.
java.naming.factory.initial=org.activemq.jndi.ActiveMQInitialContextFactory
#  Server location, change according to your enviroment.
java.naming.provider.url=tcp://localhost:61616
#  Connection factory names.
connectionFactoryNames=CommonConnectionFactory
# Queue name.
queue.ConsignmentQueue=ConsignmentQueue

###########################################################

## Consignment Reciever Properties
#  Provider url, change according to your enviroment.
provider.url=tcp://localhost:61616
# Queue name.
queue.name=ConsignmentQueue
# Change a directory in client machine to store consignment requests.
consignment.dir=/home/lsf/Lasantha/Temp/consignment

The next important part of this sample application is how to send messages and listen them from out side the application server context. Consignment sender and reciever will demonstrate those features in the application.


			Context ctx = new InitialContext(env);
			
			QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup(propLoader.getValue(CONNECTION_FACTORY_NAMES));
			
			conn = factory.createQueueConnection();
			
			Queue myQueue = (Queue) ctx.lookup(propLoader.getValue(QUEUE_NAME));
			
			session = conn.createQueueSession(false,javax.jms.Session.AUTO_ACKNOWLEDGE);

			producer = session.createProducer(myQueue);

			conn.start();
			
			consignmentMessage = session.createTextMessage();
			
			consignmentMessage.setText(content);
			
			producer.send(consignmentMessage);
			
			System.out.println("Consignment Sent !!!"); 

How to listen on a JMS queue other than a MDB? The answer for this question can be found in the consignment reciever application.

Code Block
java
java
borderStylesolid
titleConsignmentReciever.java

			System.out.println("Start Listening Consignment Data ");
			
			ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(propLoader.getValue(PROVIDER_URL));
			connection = (QueueConnection)connectionFactory.createConnection();
			connection.start();
			
			session = connection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
			Queue queue = session.createQueue(propLoader.getValue(QUEUE_NAME));
			consumer = session.createConsumer(queue);
			while(true){
				Message message = consumer.receive();
				processMessage(message);
			}

Tools used

The tools used for developing and building the order placement application are:

...

All JMS specific resource information can be found in the config/jms-resource-plan.xml file. Please follow Follow given to deployment, after logged in to the Geronimo console.

  1. Select Deploy New link from the Console Navigation in the left.
  2. Load the <geronimo_home>/repository/geronimo/ge-activemq-rar/1.1/ge-activemq-rar-1.1.rar file to the Archive field.
  3. Load the Order/config/jms-resource-plan.xml file to the Plan input field.
  4. Press Install button. Make sure Start app after install is selected when this deployment happens
  5. After you get the Upon successful installation message, verify the deployment traversing JMS resources link. It will display the connection factory and two JMS queues.

Modify Property Files

This application has two different very important property files in the config folder namely build.properties and order_mgmt.properties. Build process of the application is entirely depends on the build.propeties while and application will use order_mgmt.properties to load application related properties.

Set the correct paths to the xdoclet.home and geronimo.home directories to work application build process correctly.

This build script depends on XDoclet version 1.2.3 and Geronimo 1.1.
Code Block
xml
xml
borderStylesolid
title
Note
order_mgmt.properties

...


## Set the Geronimo 1.1 Home
geronimo.home=/home/lsf/Lasantha/geronimo-1.1

## Set the XDoclet Home 
xdoclet.home=/home/lsf/Lasantha/xdoclet-1.2.3
Note

This build script depends on XDoclet version 1.2.3 and Geronimo 1.1.

Code Block
xml
xml
borderStylesolid
titleorder_mgmt.properties

###########################################################

## Order Sender(Web Application) Properties
#  Connection Factory Name. 
jms.connection=java:comp/env/jms/CommonConnectionFactory
# Queue Name.
jms.queue=java:comp/env/jms/OrderQueue

###########################################################

## Order Reciever(EJB Application) Properties
#  Change a directory in server to store order requests. 
order.repo=/home/lsf/Lasantha/Temp/order

###########################################################

## Consignment Sender Properties
#  Queue connection factory type.
java.naming.factory.initial=org.activemq.jndi.ActiveMQInitialContextFactory
#  Server location, change according to your enviroment.
java.naming.provider.url=tcp://localhost:61616
#  Connection factory names.
connectionFactoryNames=CommonConnectionFactory
# Queue name.
queue.ConsignmentQueue=ConsignmentQueue

###########################################################

## Consignment Reciever Properties
#  Provider url, change according to your enviroment.
provider.url=tcp://localhost:61616
# Queue name.
queue.name=ConsignmentQueue
# Change a directory in client machine to store consignment requests.
consignment.dir=/home/lsf/Lasantha/Temp/consignment

order_mgmt.properties file given is shared among four defferent application components. You may have to change those properties according to your local enviroment as given below.

  1. Order Reciever Application
    Point order.repo to a directory in the application server host.
  2. Consignment Sender Application
    Change java.naming.provider.url value according to the application server network information.
  3. Consignment Reciever Application
    Both provider.url and consignment.dir properties has to be changed. provider.url has to change according to server network information. consignment.dir need to point to a directory in the application deployed machine.
Note

If you deploy one of these application components out side of application server, make sure to change the relevant network property in the above mentioned property file.

Building

Use a command prompt to navigate into the Order directory and just give ant command to build. It will create the Order.ear, recvclient.jar and sendclient.jar under the Order/releases folder. Also note it will create a lib folder and copy list of jar files refered by the remote client applications. Now you are ready to deploy order processing application in to the Geronimo Application server.

Deploying

Deploying Order processing sample application is pretty much the same as the deployment of JMS resources.

  1. Travel Deploy New from the Console Navigation.
  2. Load Order.ear from Order/releases folder in to the Archive input box.
  3. Press Install button to deploy application in the server.

Back to Top

Testing of the Sample Application
Anchor
testing
testing

Core business functionality of the order processing application is shared among the three different client applications. Testing of each client is can be done as given.

Order Placement Web Application

To test the sample web application open a browser and type http://localhost:8080/OrderImage Added. It will forward you in to the Order Management Welcome page. Then user has to fill the necessary information for the order placement and submit it.

Image Added

Consignment Placement Remote Application

This application will send consignment requests to the consignment queue. It will take consignment file as a command line argument and send it to the relevant queue. For the testing of this application a sample consignment has been given with the appication archive as Order/config/sample-consignment.xml. First travel to the Order/releases from a command prompt and give the following command.

java -jar sendclient.jar <home>/Order/config/sample-consignment.xml

No Format
bgColor#000000
borderStylesolid

lsf@lsf-laptop:~/workspace/Order/releases$ java -jar sendclient.jar /home/lsf/workspace/Order/config/sample-consignment.xml
30/08/2006 09:21:00 org.activemq.ActiveMQConnection statusChanged
INFO: channel status changed: Channel: TcpTransportChannel: Socket[addr=localhost/127.0.0.1,port=61616,localport=45177] has connected
Consignment Sent !!!

Consignment Listener Remote Application

Listener application to the consignment queue. It will download the consignment requests in the local repository. As in the above mentioned application first travel to the Order/releases from a command prompt. After that issue following command to start listening on the consignment queue.

java -jar recvclient.jar

No Format
bgColor#000000
borderStylesolid

lsf@lsf-laptop:~/workspace/Order/releases$ java -jar recvclient.jar
Start Listening Consignment Data
30/08/2006 09:22:13 org.activemq.ActiveMQConnection statusChanged
INFO: channel status changed: Channel: TcpTransportChannel: Socket[addr=localhost/127.0.0.1,port=61616,localport=45178] has connected
Received a Consignment:
<?xml version="1.0" encoding="UTF-8"?><Consignment id="001">    <Branch id="123"/>      <Orders>                <Order orderId="234" custId="889" qty="90" model="101"/>              <Order orderId="235" custId="776" qty="69" model="102"/>                <Order orderId="236" custId="245" qty="74" model="103"/>              <Order orderId="237" custId="232" qty="55" model="105"/>                <Order orderId="238" custId="354" qty="44" model="106"/>              <Order orderId="239" custId="267" qty="97" model="107"/>        </Orders></Consignment>

Building

Use a command prompt to navigate into the Order directory and just give ant command to build. It will create the Order.ear, recvclient.jar and sendclient.jar under the Order/releases folder. Also note it will create a lib folder and copy list of jar files refered by the remote client applications. Now you are ready to deploy order processing application in to the Geronimo Application server.

Deploying

Deploying Order processing sample application is pretty same as the deployment of JMS resources.

  1. Travel Deploy New from the Console Navigation.
  2. Load Order.ear from Order/releases folder in to the Archive input box.
  3. Press Install button to deploy application in the server.

Back to Top

...

Core business functionality of the order processing application is shared among the three different client applications.

Order Placement Web Application

To test the sample web application open a browser and type http://localhost:8080/OrderImage Removed. It will forward you in to the Order Management Welcome page. Then user has to fill the necessary information for the order placement and submit it.

Image Removed

Consignment Placement Remote Application

This application will send consignment requests to the consignment queue. It will take consignment file as a command line argument. Sample consignment has been given with the appication archive as Order/config/sample-consignment.xml. First travel to the Order/releases from a command prompt and give the following command.

java -jar sendclient.jar <home>/Order/config/sample-consignment.xml

Image Removed

Consignment Listener Remote Application

Listener application to the consignment queue. It will download the consignment requests in the local repository. As in the above mentioned application first travel to the Order/releases from a command prompt. After that issue following command to start listening on the consignment queue.

java -jar recvclient.jar

Note

Always consider lib folder inside of releases are a part of this client application. It contains library files you need to add to your class path to call a JMS application. Check your Operating Sytem's security configuration when if you are connecting from a remote machine.

...

This article has demontrated how to use JMS features in Apache Geronimo with the ActiveMQ JMS server.It provides a hypothical example which extensively used JMS features to application processing.

Following are some of the highlights in this article.

  • Apache Geronimo is a J2EE 1.4 Certified application server and it provides all the necessary features to support asynchronous mode of communication in enterprise applications.
  • Define JMS connection factories and related queues in a Geronimo enviroment.
  • Message Driven Beans are the components are listener application components provides by J2EE container. This article has shown how to define them effective mannerlistening on JMS queues providing by the J2EE container.
  • Sending and recieving data to a defined queue as a remote client to the application server.