You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

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 way. Introduction of Java Messaging Service (JMS) 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. Apache Geronimo comes in to the party with support of JMS integrating one of the best breed open source messaging frameworks ActiveMQ. This article will guide you a way to use JMS/MDBs for in enterprise application scenario in both as a locally and remotely reffered enviroments with Geronimo and ActiveMQ.

The company reffered in this sample application sales 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 handed over to a sales employee. This is a typical application to 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 in your Enterprise Application with ease.

This article is organized in to following sections.

Overview of JMS in Geronimo/ActiveMQ Enviroment

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

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 ActiveMQ supports MDBs, which are EJBs that consume JMS messages. It allows enterprise application to take J2EE specific features from Geronimo. Application components such as JSPs, Servlets or EJBs utilizing JMS must access message broker through a library that implements the JMS API. This API has been implemented in an abstract layer to support any JMS provider. Geronimo has achieved this this feature using 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).

Application Overview

Order processing application has two defined 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 to the order queue, the Order recv MDB will be triggered. Those order requests are saved in the server repository for the later authorization by a company employee. Compnay's sales agents are using the Consignment Sender application to send consignment requests from their locations. First they will prepare consignments as XML files, then it will be given it to that application. Consignment Sender application will read the content of the consignment and send it to the Consignment queue. Senior manager in the company uses Consignment Reciever application to find out the consignment requests. When a consignment request reached to the Consignment queue, Consignment Reciever listener application will download those requests to the responsible manager's computer.

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

Application contents

The order placement application consist of following list of packages and classes.

  • 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 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 order placement application will be deployed as an EAR to the application server. Overview of the contents of EAR is given in the following.

|-Order.ear
   |-OrderEjb.jar
	|-META-INF
	    |- ejb-jar.xml
	    |- openejb-jar.xml
   |-OrderWeb.war
	|-jsp
            |- index.jsp
	    |- error.jsp
	|-WEB-INF
	    |- web.xml
	    |- geronimo-web.xml
	    |- classes
   |-META-INF
        |- application.xml
        |- geronimo-application.xml

First we will look at how to define connection factories and queues in the Geronimo server using jms-resource-plan.xml. It defines two JMS queues and a common queue connection factory to access them.

jms-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 openejb-jar.xml defines Geronimo specific features of MDBs. It links OrderRecv MDB with OrderQueue via CommonConnectionFactory.

openejb-jar.xml
<openejb-jar xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.1" xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.1" xmlns:security="http://geronimo.apache.org/xml/ns/security-1.1" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.1">
  <sys:environment>
    <sys:moduleId>
      <sys:groupId>samples</sys:groupId>
      <sys:artifactId>OrderEjb</sys:artifactId>
      <sys:version>1.0</sys:version>
      <sys:type>car</sys:type>
    </sys:moduleId>
    <sys:dependencies>
		<sys:dependency>
			<sys:groupId>geronimo</sys:groupId>
			<sys:artifactId>activemq-broker</sys:artifactId>
			<sys:version>1.1</sys:version>
			<sys:type>car</sys:type>
        </sys:dependency>
		<sys:dependency>
            <sys:groupId>samples</sys:groupId>
            <sys:artifactId>jms-resources</sys:artifactId>
            <sys:version>1.0</sys:version>
            <sys:type>rar</sys:type>
        </sys:dependency>
    </sys:dependencies>
    <sys:hidden-classes/>
    <sys:non-overridable-classes/>
  </sys:environment>
  <enterprise-beans>
    <message-driven>
      <ejb-name>OrderRecvMDB</ejb-name>
		<resource-adapter>
			<resource-link>CommonConnectionFactory</resource-link>
      	</resource-adapter>
		<activation-config>
		  <activation-config-property>
		    <activation-config-property-name>destination</activation-config-property-name>
		    <activation-config-property-value>OrderQueue</activation-config-property-value>
		  </activation-config-property>
		  <activation-config-property>
		    <activation-config-property-name>destinationType</activation-config-property-name>
		    <activation-config-property-value>javax.jms.Queue</activation-config-property-value>
		  </activation-config-property>
		</activation-config>
    </message-driven>
  </enterprise-beans>
</openejb-jar>

geronimo-application.xml and application.xml define the main components of the EAR. Both EJB component and Web archive information are given in this files as usual.

geronimo-application.xml
<application xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.1">
  <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1">
    <dep:moduleId>
      <dep:groupId>samples</dep:groupId>
      <dep:artifactId>Order</dep:artifactId>
      <dep:version>1.0</dep:version>
      <dep:type>car</dep:type>
    </dep:moduleId>
    <dep:dependencies/>
    <dep:hidden-classes/>
    <dep:non-overridable-classes/>
  </dep:environment> 
</application>
application.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>

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.

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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/web-app_2_4.xsd"
		version="2.4">
	
	<servlet>
		<display-name>OrderSenderServlet</display-name>
		<servlet-name>OrderSenderServlet</servlet-name>
		<servlet-class>org.apache.geronimo.samples.order.web.OrderSenderServlet</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>OrderSenderServlet</servlet-name>
		<url-pattern>/order</url-pattern>
	</servlet-mapping>	
	
	<resource-ref>
	    <res-ref-name>jms/CommonConnectionFactory</res-ref-name>
	    <res-type>javax.jms.QueueConnectionFactory</res-type>
	    <res-auth>Container</res-auth>
	    	<res-sharing-scope>Shareable</res-sharing-scope>
 	</resource-ref>
	
	<message-destination-ref>
	    <message-destination-ref-name>jms/OrderQueue</message-destination-ref-name>
	    <message-destination-type>javax.jms.Queue</message-destination-type>
	    <message-destination-usage>Produces</message-destination-usage>
	    <message-destination-link>OrderQueue</message-destination-link>
	</message-destination-ref>
	
	<welcome-file-list>
		<welcome-file>/jsp/index.jsp</welcome-file>
	</welcome-file-list>
	
</web-app>

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

geronimo-web.xml will act as the 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.

geronimo-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 file.

order_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

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.

Tools used

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

XDoclet

XDoclet is an open source code generation engine. It enables Attribute-Oriented Programming for java. In short, this means that you can add more significance to your code by adding meta data (attributes) to your java sources. This is done in special JavaDoc tags.
Although XDoclet originated as a tool for creating EJBs, it has evolved into a general-purpose code generation engine. XDoclet consists of a core and a constantly growing number of modules. It is fairly straightforward to write new modules if there is a need for a new kind of component.
http://xdoclet.sourceforge.net/xdoclet/index.html

Eclipse

The Eclipse IDE was used for development of the sample application. This is a very powerful and popular open source development tool. It has integration plug-ins for the Geronimo too. Eclipse can be downloaded from the following URL:
http://www.eclipse.org

Apache Ant

Ant is a pure Java build tool. It is used for building the war files for the Inventory application. Ant can be downloaded from the following URL:
http://ant.apache.org

Back to Top

Configuring, Building and Deploying the Sample Application

Download the order processing application from the following link:
Order

After decompressing the given file, the Order directory is created.

Configuring

Configuration of the application consists of creating the database and defining the connection pool to access it.

Creating JMS Specific Resources

Modify Property Files

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

Building

Deploying

Back to Top

Testing of the Sample Application

Order Placement Web Application

Order Placement Remote Application

Always consider lib folder inside of releases are a part of this client application.Check your Operating Sytem's security configuration when you are connecting from a remote machine.

Summary

  • No labels