OC4J JMS Resource Adapter demo for WebSphere MQ®

Date: 02/12/2003

Table of Contents

Introduction
Application Overview
Application Design
Sample Application Files
Setting Up the Sample Application
Additional References


Introduction 

Prerequisite

This demo assumes that the reader has knowledge of the following:

Technical Overview

The J2EE Connector Architecture is a required J2EE 1.3 API. It defines a standard architecture for connecting the J2EE platform to heterogeneous Enterprise Information Systems (EISs). A Resource Adapter is a driver that an application server or an application client uses to connect to a specific EIS.

A stand-alone resource adapter, materialized by a stand-alone Resource Adapter Archive (RAR) file, is available to all deployed applications in the application server instance.

An embedded resource adapter, bundled within an enterprise application archive (EAR), is available only to the J2EE application with which it is packaged.

J2EE 1.3 requires application servers to support the deployment of both stand-alone and embedded resource adapters. OC4J supports three resource adapter deployment descriptors: ra.xml, oc4j-ra.xml, and oc4j-connectors.xml.

ra.xml: This is the standard J2EE deployment descriptor for developing resource adapters. The ra.xml descriptor is always supplied with the resource adapter.

oc4j-ra.xml: This file contains deployment configurations for deploying resource adapters to OC4J. It contains EIS connection information as specified in the deployment descriptor of the resource adapter (ra.xml), JNDI name to be used, connection pooling parameters, and resource principal mappings (security-config element). Whenever you deploy a resource adapter, OC4J generates oc4j-ra.xml if the file does not already exist in the archive.

oc4j-connectors.xml: In an OC4J instance with stand-alone resource adapters deployed, this file contains a list of stand-alone resource adapters that have been deployed in this OC4J instance. In J2EE application with embedded resource adapters deployed, this file contains a list of embedded resource adapters that have been bundled with the application. OC4J generates
oc4j-connectors.xml if it does not exist in the archive.

Application Overview 

This application showcases Oracle Application Server Containers for J2EE 10g JCA 1.5 support and Oracle's generic JMS Resource Adapter. This particular How-To describes how to configure the generic JMS Resource Adapter to work with WebSphere MQ (formerly MQSeries).

Application Design 

This section will detail application design notes that will help you appreciate the design decisions that went into developing this sample application, the architecture diagram that lets you visualize how different components fit together in the overall scheme of the application, and code snippets that help you relate the implementation of concepts in code.

Design Notes 

The application consists of a web component (servlet) and ejb component (mdb). The servlet sends a message to a JMS queue on which an MDB is listening on. The MDB upon receipt of the message sends a reply message back to the queue, linking the received and reply messages using JMSCorrelationID. The servlet waits for the reply and verifies that all replies are correctly received. The architecture diagram illustrates this scenario.

WebSphere MQ JMS provider is used for this illustration. The application demonstrates the following concepts:

Architecture Diagram 

Configuration Support

A Resource Adapter is a driver that an application server or an application client uses to connect to a specific EIS.

This application provides Resource Adapter aRchive mqjra.rar (located in the directory jcajmsmq\dist) which has been configured to connect to WebSphere MQ. This archive contains:

 
gjra.jar
JAR file containing the generic JMS resource adapter classes provided by OC4J
meta-inf\
ra.xml
The standard J2EE deployment descriptor for Resource Adapter
meta-inf\
oc4j-ra.xml
OC4J specific additional Resource Adapter configuration information

The following configurations are set in ra.xml to enable access to the WebSphere MQ Queue and Topic:

<connector...>
    ...
    <resourceadapter>
<resourceadapter-class>oracle.j2ee.ra.jms.generic.JMSResourceAdapter</resourceadapter-class> ...
<config-property>
<config-property-name>resourceProviderName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>MQSeries</config-property-value>
</config-property>
<!-- Queue admin object -->
<adminobject>
<adminobject-interface>javax.jms.Queue</adminobject-interface>
<adminobject-class>oracle.j2ee.ra.jms.generic.AdminObjectQueueImpl</adminobject-class>
<config-property>
<config-property-name>jndiName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>MQQ</config-property-value>
</config-property>
<config-property>
<config-property-name>resourceProviderName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>MQSeries</config-property-value>
</config-property>
</adminobject> <!-- Topic admin object -->
<adminobject>
<adminobject-interface>javax.jms.Topic</adminobject-interface>
<adminobject-class>oracle.j2ee.ra.jms.generic.AdminObjectTopicImpl</adminobject-class>
<config-property>
<config-property-name>jndiName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>MQT</config-property-value>
</config-property>
<config-property>
<config-property-name>resourceProviderName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>MQSeries</config-property-value>
</config-property>
</adminobject> <!-- inbound configuration -->
<inbound-resourceadapter> ... </inbound-resourceadapter> <!-- outbound configuration -->
<outbound-resourceadapter>
<connection-definition>
<managedconnectionfactory-class>oracle.j2ee.ra.jms.generic.ManagedXAQueueConnectionFactoryImpl </managedconnectionfactory-class> ...
<config-property>
<config-property-name>jndiLocation</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>MQXAQCF</config-property-value>
</config-property>
</connection-definition> <connection-definition>
<managedconnectionfactory-class>oracle.j2ee.ra.jms.generic.ManagedQueueConnectionFactoryImpl </managedconnectionfactory-class>
...
<config-property>
<config-property-name>jndiLocation</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>MQQCF</config-property-value>
</config-property>
</connection-definition> <connection-definition>
<managedconnectionfactory-class>oracle.j2ee.ra.jms.generic.ManagedXATopicConnectionFactoryImpl </managedconnectionfactory-class>
...
<config-property>
<config-property-name>jndiLocation</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>MQXATCF</config-property-value>
</config-property>
</connection-definition> <connection-definition>
<managedconnectionfactory-class>oracle.j2ee.ra.jms.generic.ManagedTopicConnectionFactoryImpl </managedconnectionfactory-class>
...
<config-property>
<config-property-name>jndiLocation</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>MQTCF</config-property-value>
</config-property>
</connection-definition> ...
</outbound-resourceadapter>
</resourceadapter>
</connector>

The Resource Provider Name is set as 'MQSeries'. 'MQQ', 'MQT', 'MQQCF', 'MQTCF', 'MQXATCF', 'MQXATCF' are the JNDI bound JMS objects created using JMSAdmin of WebSphere MQ which can now be looked up by the application. These can be found in the .bindings file created while configuring WebSphere MQ JMS Provider. Refer to Step 3 in the Install.html.

The OC4J specific configurations are set in oc4j-ra.xml as follows:

<oc4j-connector-factories>
  <connector-factory location="mqjms/MyQCF" connector-name="MQJMS">
<managedconnectionfactory-class>
oracle.j2ee.ra.jms.generic.ManagedQueueConnectionFactoryImpl
</managedconnectionfactory-class> <config-property name="jndiLocation" value="MQQCF"/>
</connector-factory> <connector-factory location="mqjms/MyXAQCF" connector-name="MQJMS">
<managedconnectionfactory-class>
oracle.j2ee.ra.jms.generic.ManagedXAQueueConnectionFactoryImpl
</managedconnectionfactory-class>
<config-property name="jndiLocation" value="MQXAQCF"/>
</connector-factory> <connector-factory location="mqjms/MyTCF" connector-name="MQJMS">
<managedconnectionfactory-class>
oracle.j2ee.ra.jms.generic.ManagedTopicConnectionFactoryImpl
</managedconnectionfactory-class>
<config-property name="jndiLocation" value="MQTCF"/>
</connector-factory> <connector-factory location="mqjms/MyXATCF" connector-name="MQJMS">
<managedconnectionfactory-class>
oracle.j2ee.ra.jms.generic.ManagedXATopicConnectionFactoryImpl
</managedconnectionfactory-class>
<config-property name="jndiLocation" value="MQXATCF"/>
</connector-factory> </oc4j-connector-factories>

mqjra.rar can be readily used by any application which requires to connect to WebSphere MQ configured with similar JMS objects.

OC4J JCA requires the JMS provider's destination to be mapped into the JCA JNDI namespace. This is done by configuring the rar details in oc4j-connectors.xml as follows:

<oc4j-connectors>
<connector name="mqjms" path="mqjra.rar" > <adminobject-config location="mqjms/MyQ">
<adminobject-class>oracle.j2ee.ra.jms.generic.AdminObjectQueueImpl</adminobject-class>
<config-property name="jndiName" value="MQQ"/>
<config-property name="resourceProviderName" value="MQSeries"/>
</adminobject-config> <adminobject-config location="mqjms/MyT">
<adminobject-class>oracle.j2ee.ra.jms.generic.AdminObjectTopicImpl</adminobject-class>
<config-property name="jndiName" value="MQT"/>
<config-property name="resourceProviderName" value="MQSeries"/>
</adminobject-config> </connector>
</oc4j-connectors>

OC4J requires that the path to oc4j-connectors.xml should be defined in orion-application.xml along with the Resource Provider specific details:

<orion-application>
  ...
  <resource-provider 
class="com.evermind.server.deployment.ContextScanningResourceProvider" name="MQSeries">
<description>MQSeries resource provider</description>
<property name="java.naming.factory.initial" value="com.sun.jndi.fscontext.RefFSContextFactory">
</property>
<property name="java.naming.provider.url"
value="file:/var/mqm/jndi">
</property>
</resource-provider> <connectors path="./oc4j-connectors.xml"/> </orion-application>

The application uses the rar as an embedded resource adapter meaning that the rar is bundled along with the EAR. The following entry is added to application.xml in the EAR file:

<application>
  ...
<!-- Resource Adapter -->
<module>
<connector>mqjra.rar</connector>
</module>
</application>

Code Support

The previous section explains the configurations required to make the JMS provider WebSphere MQ available to the applications. This section explains the configurations and code required in the application to make use of the configuration details and send/receive messages from JMS Topic/Queue.

Configuring EJBs to connect to the JMS Topic/Queue

To enable EJB's specifically MDBs in this application to connect to the JMS Topic/Queue, the OC4J specific EJB deployment descriptor orion-ejb-jar.xml should be configured as follows:

<orion-ejb-jar ...>
  <enterprise-beans>
<message-driven-deployment name="simpleMdb" resource-adapter="mqjms">
<resource-ref-mapping name="jms/XAQCF" location="mqjms/MyXAQCF" />
<resource-env-ref-mapping name="jms/QUEUE1" location="mqjms/MyQ" />
</message-driven-deployment> <message-driven-deployment name="PSsimpleMdb" resource-adapter="mqjms">
<resource-ref-mapping name="jms/XATCF" location="mqjms/MyXATCF" />
<resource-env-ref-mapping name="jms/TOPIC1" location="mqjms/MyT" />
</message-driven-deployment>
</enterprise-beans> ... </orion-ejb-jar>

Note that the value of location attributes defined here correspond to the value of location attributes defined in oc4j-ra.xml and oc4j-connectors.xml.

The reference mapping names specified can now be used in the J2EE standard EJB deployment descriptor ejb-jar.xml as follows:

<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>simpleMdb</ejb-name> ... <resource-ref>
...
<res-ref-name>jms/XAQCF</res-ref-name>
<res-type>javax.jms.XAQueueConnectionFactory</res-type>
...
</resource-ref> <resource-env-ref>
...
<resource-env-ref-name>jms/QUEUE1</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>
</message-driven> <message-driven>
<ejb-name>PSsimpleMdb</ejb-name> ...
<resource-ref>
... <res-ref-name>jms/XATCF</res-ref-name>
<res-type>javax.jms.XATopicConnectionFactory</res-type>
... </resource-ref> <resource-env-ref>
... <resource-env-ref-name>jms/TOPIC1</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
... </resource-env-ref>
</message-driven>
</enterprise-beans> ... </ejb-jar>

The resource references set in ejb-jar.xml are used in the application to access the JMS Queue/Topic.
The code in the MDB to access the JMS Queue are as follows:

    ...

    private XAQueueConnectionFactory m_xaqcf = null;
private Queue m_replyq = null;
Context ctx = new InitialContext(); m_xaqcf = (XAQueueConnectionFactory) ctx.lookup("java:comp/env/jms/XAQCF"); m_replyq = (Queue) ctx.lookup("java:comp/env/jms/QUEUE1"); ...

The code in the MDB to access the JMS Topic are as follows:

    ...
    private XATopicConnectionFactory m_xatcf = null;
private Topic m_replyt = null;
Context ctx = new InitialContext(); m_xatcf = (XATopicConnectionFactory)ctx.lookup("java:comp/env/jms/XATCF"); m_replyt = (Topic) ctx.lookup("java:comp/env/jms/TOPIC1");
...

Configuring Web Applications to connect to the JMS Topic/Queue

To enable Web Applications specifically servlets in this application to connect to the JMS Topic/Queue, the OC4J specific web deployment descriptor orion-web.xml should be configured as follows:

<orion-web-app ...>
<resource-ref-mapping name="jms/QCF" location="mqjms/MyQCF" />
<resource-ref-mapping name="jms/XAQCF" location="mqjms/MyXAQCF" />
<resource-env-ref-mapping name="jms/QUEUE1" location="mqjms/MyQ" />
<resource-ref-mapping name="jms/TCF" location="mqjms/MyTCF" />
<resource-ref-mapping name="jms/XATCF" location="mqjms/MyXATCF" />
<resource-env-ref-mapping name="jms/TOPIC1" location="mqjms/MyT" />
</orion-web-app>

Note that the value of location attributes defined here correspond to the value of location attributes defined in oc4j-ra.xml and oc4j-connectors.xml.

The reference mapping names specified can now be used in the J2EE standard web deployment descriptor web.xml as follows:

<web-app>
  ...
  <resource-env-ref>
<resource-env-ref-name>jms/QUEUE1</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref> <resource-ref>
<res-ref-name>jms/QCF</res-ref-name>
<res-type>javax.jms.QueueConnectionFactory</res-type>
<res-auth>Application</res-auth>
</resource-ref> <resource-ref>
<res-ref-name>jms/XAQCF</res-ref-name>
<res-type>javax.jms.XAQueueConnectionFactory</res-type>
<res-auth>Application</res-auth>
</resource-ref> <resource-env-ref>
<resource-env-ref-name>jms/TOPIC1</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
</resource-env-ref> <resource-ref>
<res-ref-name>jms/TCF</res-ref-name>
<res-type>javax.jms.TopicConnectionFactory</res-type>
<res-auth>Application</res-auth>
</resource-ref> <resource-ref>
<res-ref-name>jms/XATCF</res-ref-name>
<res-type>javax.jms.XATopicConnectionFactory</res-type>
<res-auth>Application</res-auth>
</resource-ref>
</web-app>

The resource references set in web.xml are used in the application to access the JMS Queue/Topic.
The code in the servlet to access the JMS Queue are as follows:

    ...
    private String m_factoryName = "java:comp/env/jms/QCF";
private String m_qName = "java:comp/env/jms/QUEUE1";
QueueConnectionFactory qcf = (QueueConnectionFactory)jndiLookup(m_factoryName); Queue ourQ = (Queue)jndiLookup(m_qName);
...

The code in the servlet to access the JMS Topic are as follows:

    ...
    private String m_factoryName = "java:comp/env/jms/TCF";
private String m_tName = "java:comp/env/jms/TOPIC1";
TopicConnectionFactory tcf = (TopicConnectionFactory)jndiLookup(m_factoryName); Topic ourT = (Topic)jndiLookup(m_tName);
...

Sample Application Files 

This section will provide a tabular listing of the sample application files, along with their respective directory locations and a description of what they do in the overall scheme of the application:

Build files and Scripts

Directory File Description

jcajmsmq

build.xml

This is the ANT build file used to build and deploy the application

jcajmsmq

common.xml

This file is used by build.xml to access common environment variables

jcajmsmq mqManager.bat, mqManagerAdd.bat, mqBindings.bat, mqManagerStop.bat These are the Windows batch scripts used to setup the WebSphere MQ environment for running this application
mqManager.sh, mqBindings.sh, mqManagerStop.sh These are the Unix / Linux batch scripts used to setup the WebSphere MQ environment for running this application
jcajmsmq mqObjects.mqsc This file is used by the batch scripts to define JMS Channel, Queue and Topic

Doc files and Stylesheets

Directory File Description

jcajmsmq\doc

Readme.html

This file

jcajmsmq\doc Install.html This file contains the step-by-step instructions to install and run the application
jcajmsmq\doc otn.css The stylesheet used for the Install and Readme html files
jcajmsmq\doc\images figure1.gif This is the image file referenced in this Readme file

Configuration files for the Application

Directory File Description

jcajmsmq\etc

application.xml

This file is used to define the J2EE EAR file, which contains the location of MDB JAR file, Web application WAR file, Resource Adapter RAR file and
is included in the EAR file.

jcajmsmq\etc ejb-jar.xml This file is the standard J2EE EJB deployment descriptor which contains the details description and deployment information for the MDB classes
jcajmsmq\etc web.xml This file is the standard J2EE web deployment descriptor which contains the servlet deployment details and the resource reference information
jcajmsmq\etc oc4j-connectors.xml This file contains OC4J specific Resource Adapter configuration information
jcajmsmq\etc orion-application.xml This file contains the application specific library paths and Resource provider configuration information
jcajmsmq\etc orion-ejb-jar.xml This file contains OC4J specific additional EJB deployment description
jcajmsmq\etc orion-web.xml This file contains OC4J specific additional web deployment description
jcajmsmq\etc\rar\META-INF ra.xml This file contains the standard J2EE deployment descriptor for Resource Adapter
jcajmsmq\etc\rar\META-INF oc4j-ra.xml This file contains OC4J specific additional Resource Adapter configuration information

MDB Source files for the Application

Directory File Description

jcajmsmq\mdb

simpleMdb.java

This implements MessageDrivenBean and MessageListener and accesses the JMS Queue

jcajmsmq\mdb PSsimpleMdb.java This implements MessageDrivenBean and MessageListener and accesses the JMS Topic

Servlet Source files for the Application

Directory File Description

jcajmsmq\web

jmsDemoServlet.java

This servlet is used to send/receive messages to/from JMS Queues

jcajmsmq\web PSjmsDemoServlet.java This servlet is used to send/receive messages to/from JMS Topic

Resource Adapter aRchive

Directory File Description

jcajmsmq\dist

mqjra.rar

This is the Resource Adapter aRchive (RAR) containing the Resource Adapter and OC4J configuration files used by the application to connect to WebSphere MQ

Setting Up the Sample Application 

Refer the Install.html for step-by-step instructions on extracting files, installing and running the application successfully.

Additional References 


Websphere MQ (formerly MQSeries) is a registered trademark of International Business Machines (IBM Corp.)
We hope you find this README file helpful. Please enter your comments about this sample in the OTN Sample Code Discussion Forum.