How to Configure and use Active MQ JCA 1.5 Resource Adapter with OC4J 10g (10.1.3)?

First Created: 09-15-2006
Author:  
Sandeep Bangera


Introduction

g  


Outbound Communication:
Inbound Communication:

Prerequisites

What you need to know

  • You should be familiar with these technologies: JMS, MDB, EJB;
  • Link to other OC4J Howto's on OTN

Software Requirements

  • Oracle Containers for J2EE 10g (10.1.3) , standalone version, with a web site configured (example http-web-site)
  • Sun's JDK version 1.5 or above, available here
  • Apache Ant 1.6.2 or above, to build the application, available from here
  • ActiveMQ  4.0.1 or above, available from here
  • Any HTML browser like Mozilla, Microsoft Internet Explorer, Netscape, etc.

Notations

  • %ORACLE_HOME% - The directory you installed OC4J too.
  • %JAVA_HOME% - The directory where your JDK is installed
  • %ACTIVEMQ_HOME% - The directory where you installed ActrveMQ
  • %HOWTO_HOME% - The directory where this demo is unzipped

Building the Application

%HOWTO_HOME%/doc/javadoc/
%HOWTO_HOME%/etc


Overview

Howto Architecture

The above diagram shows the message flow in the howto example. A standlaone JMS client generates a JMS TextMessage and places it on the queue queue.inbound. These inbound messages are consumed by MDB which then invokes the Stateless EJB. The Stateless EJB takes the input from the MDB and publishes a simple response message to the queue.outbound queue.

 

Updating ActiveMQ rar to be OC4J deployable .


  • Unzip the original ActiveMQ Resource Adapter file %ACTIVEMQ_HOME%/lib/optional/activemq-ra-4.0.1.rar  to say  C:/temp
  • Add oc4j-ra.xml present in %HOWTO_HOME%/etc/connector to the unzipped location i.e. C:/temp/META-INF
  • Modify ra.xml and uncomment the embeded broker usage
    <!--
       <config-property-value>xbean:broker-config.xml</config-property-value>
    -->
    <!-  
        <config-property-value>vm://localhost</config-property-value>
    -->
  • Remove all the required jars except the main ra.jar  i.e.  activemq-ra-4.0.1.jar. The ra required jars will be published as a shared library available to the application.
  • Create  a new rar with the above modified contents
    jar -cvfm C:\temp\activemq-ra.rar META-INF/MANIFEST.MF META-INF/* activemq-ra-4.0.1.jar broker-config.xml
  • Copy the new activemq-ra.rar from previous step to  %HOWTO_HOME%/activemq-lib
Note:These steps are already done in the current howto for ActiveMQ 4.0.1 release. If you are using a more recent release of ActiveMQ then you may need to do the above steps to use the latest ActiveMQ RAR.

  •        Create a shared library of  all the  ActiveMQ Resource adapters required and publish it to OC4J. Luckily default activeMQ jar comes complete with all the libraries required by ActiveMQ. So we only export this  jar as a shared library
       <oracle:publishSharedLibrary
                  deployerUri="deployer:oc4j:${oc4j.host}:${oc4j.admin.port}"
                  userId="${oc4j.admin.user}"
                  password="${oc4j.admin.password}"
                  libraryName="${shared.library.name}"
                  libraryVersion="4.0.1"
                  logFile="${log.dir}/publish-library.log">
                  <oracle:uploadCodeSource path="${activemq.home}/${activemq.core.jar}" />
                  <!-- You may need to add these files to the shared library if you are interested
                        in ActiveMQ persistence features.
                        In adddition you will need to modify broker-config.xml in ra.jar to use spring properties -->

                  <!--
                     <oracle:uploadCodeSource path="${activemq.home}/lib/optional/spring-1.2.6.jar" />
                     <oracle:uploadCodeSource path="${activemq.home}/lib/optional/xbean-spring-2.2.jar" />
                  -->
           </oracle:publishSharedLibrary>
  • Import the shared library in orion-application.xml so that it is availabel to the ActiveMQ Resource Adapter
      <imported-shared-libraries>
         <import-shared-library name="activemq.rar" max-version="4.0.1"/>
      </imported-shared-libraries>


Inbound Communication - Configuring MDB to receive messages from ActiveMQ

 

Message Driven Bean

For the ActiveMQMessageDrivenEJBBeanIn the ejb-jar.xml deployment descriptor is declared as follows:

    <message-driven>
      <description>Message Driven Bean</description>
      <display-name>ActiveMQMessageDrivenEJB</display-name>
      <ejb-name>ActiveMQMessageDrivenEJB</ejb-name>
      <ejb-class>com.oracle.howto.activemq.ActiveMQMessageDrivenEJBBean</ejb-class>
      <messaging-type>javax.jms.MessageListener</messaging-type>
      <transaction-type>Container</transaction-type>
      <activation-config>
            <activation-config-property>
               <activation-config-property-name>destination</activation-config-property-name>
               <activation-config-property-value> queue.inbound</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-property>
               <activation-config-property-name>acknowledgeMode</activation-config-property-name>
               <activation-config-property-value>Auto-acknowledge</activation-config-property-value>
            </activation-config-property>
            <activation-config-property>
               <activation-config-property-name>messageSelector</activation-config-property-name>
               <activation-config-property-value/>
            </activation-config-property>
      </activation-config>
    </message-driven>

The activation-config-property is used to  link MDB to JCA.  The destination property value is only ActiveMQ specific and is the physical name of the queue on  which the MDB listens to.

Connector

The two activation configuration defined above link to the following elements in  ra.xml

        <inbound-resourceadapter>
            <messageadapter>
                <messagelistener>
                    <messagelistener-type>javax.jms.MessageListener</messagelistener-type>
                    <activationspec>
                        <activationspec-class>org.apache.activemq.ra.ActiveMQActivationSpec</activationspec-class>
                       
                        <required-config-property>
                            <config-property-name>destination</config-property-name>
                        </required-config-property>
                        <required-config-property>
                            <config-property-name>destinationType</config-property-name>
                        </required-config-property>
                       
                    </activationspec>
                </messagelistener>
            </messageadapter>
        </inbound-resourceadapter>

 

Additional  Glue Steps

Update orion-ejb-jar.xml with the actual dest location JNDI info.  This connects the inbound JMS Destination to the MDB
        <message-driven-deployment name="ActiveMQMessageDrivenEJB" resource-adapter="activemq-rar"
                    connection-factory-location="activeMQ/QueueConnectionFactory" destination-location="activeMQJMS/MyQ">

        </message-driven-deployment>

Update the transaction info for onMessage to be required in ejb.-jar.xml
      <container-transaction>
         <method>
            <ejb-name>ActiveMQMessageDrivenEJB</ejb-name>
            <method-name>onMessage</method-name>
            <method-params>
               <method-param>javax.jms.Message</method-param>
            </method-params>
         </method>
         <trans-attribute>Required</trans-attribute>
      </container-transaction>

Outbound Communication - Configuring a Session Bean  to send messages to ActiveMQ

Stateless Session Bean

  • The ejb-jar.xml descriptor of  ActiveMQEJBBean has the following:

         <resource-ref>
        <res-ref-name>jms/QCF</res-ref-name>
        <res-type>javax.jms.QueueConnectionFactory</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Unshareable</res-sharing-scope>
      </resource-ref>
      <resource-env-ref>
        <resource-env-ref-name>jms/QUEUE</resource-env-ref-name>
        <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
      </resource-env-ref>

The jms/QCF is the JNDI name the ActiveMQEJBBean will use to lookup a javax.jms.QueueConnectionFactory. We will configure it to point to an ActiveMQ QueueConnectionFactory.

  • Similarly link the same in orion-ejb-jar.xml to actual JNDI location


        <session-deployment name="ActiveMQEJB">
            <resource-ref-mapping     name="jms/QCF"  location="activeMQ/QueueConnectionFactory" />     
            <resource-env-ref-mapping name="jms/QUEUE" location="activeMQJMS/MyQ" />
        </session-deployment>

The Connector


        <outbound-resourceadapter>
            <connection-definition>
                <managedconnectionfactory-class>org.apache.activemq.ra.ActiveMQManagedConnectionFactory</managedconnectionfactory-class>
                <connectionfactory-interface>javax.jms.ConnectionFactory</connectionfactory-interface>
                <connectionfactory-impl-class>org.apache.activemq.ra.ActiveMQConnectionFactory</connectionfactory-impl-class>
                <connection-interface>javax.jms.Connection</connection-interface>
                <connection-impl-class>org.apache.activemq.ra.ManagedConnectionProxy</connection-impl-class>
            </connection-definition>

        <adminobject>
            <adminobject-interface>javax.jms.Queue</adminobject-interface>
            <adminobject-class>org.apache.activemq.command.ActiveMQQueue</adminobject-class>
            <config-property>
                <config-property-name>PhysicalName</config-property-name>
                <config-property-type>java.lang.String</config-property-type>
            </config-property>
        </adminobject>

Glue Code

The following snippet  links the Outbound queue .  The following snippet is in oc4j-connectors.xml 

    <connector name="activemq-rar" path="activemq-ra.rar" >
        <adminobject-config location="activeMQJMS/MyQ">
            <adminobject-class>org.apache.activemq.command.ActiveMQQueue</adminobject-class>
            <config-property name="PhysicalName" value="queue.outbound"/>
        </adminobject-config>
        <adminobject-config location="activeMQJMS/MyT">
            <adminobject-class>org.apache.activemq.command.ActiveMQTopic</adminobject-class>
            <config-property name="PhysicalName" value="topic.outbound"/>
        </adminobject-config>
    </connector>

The connection factory is linked in oc4j-ra.xml

    <connector-factory location="activeMQ/QueueConnectionFactory" connector-name="activemq-rar">
        <connection-pooling use="none">
        </connection-pooling>
        <security-config use="none">
        </security-config>
        <connectionfactory-interface>javax.jms.QueueConnectionFactory</connectionfactory-interface>
    </connector-factory>

 

 

Running the Application

The following instructions are for running this demonstration on a standalone instance of Oracle Containers for J2EE 10g (10.1.3).

Examining the Sample File Directories

  • how-to-use-activemq-JCA-RA/src/java - contains all Java source code for the example.
    • client/ 
      • ActiveMQApp.java - JMS Client which posts a message to the ActiveMQ queue.
    • ejb/
      • ActiveMQEJB.java - ActiveMQ Stateless EJB remote interface.
      • ActiveMQEJBHome.java  - ActiveMQ Stateless EJB home interface.
      • ActiveMQEJBBean.java  - ActiveMQ Stateless EJB implementation.
      • ActiveMQEJBLocal.java - ActiveMQ Stateless EJB local  interface.
      • ActiveMQEJBLocalHome.java - ActiveMQ Stateless EJB local home interface.
      • ActiveMQMessageDrivenEJBBean.java -  ActiveMQ MDB which listens  on the ActiveMQ inbound queue
  • how-to-use-activemq-JCA-RA / lib/
    • active-mq.ear - Deployable J2EE application file.
    • active-mq-client.jar - JMS Test client  jar file.
  • how-to-use-activemq-JCA-RA / etc - contains all necessary application descriptor files needed by the application
    • connector/
      • oc4j-ra.xml  - OC4J specific rar descriptor file
    • ear /
      • application.xml
      • oc4j-connectors.xml
      • orion-application.xml
    • ejb/
      • ejb-jar.xml
      • orion-ejb-jar.xml
  • how-to-use-activemq-JCA-RA /doc
    • how-to-use-activemq-JCA-RA.html - This document.
    • javadoc - the javadoc of all the source files
  • how-to-use-activemq-JCA-RA /build.xml - The main  Ant build file.
  • how-to-use-activemq-JCA-RA /common.xml - Used by build.xml
  • how-to-use-activemq-JCA-RA /ant-oracle.properties - Used by build.xml
  • how-to-use-activemq-JCA-RA /activemq-lib
    • activemq-ra-4.0.1.rar.orig - The original ActiveMQ Resource Adapter from ActiveMQ distribution in   %ACTIVEMQ_HOME%/lib/optional
    • activemq-ra.rar -  The modified ActiveMQ resource adapter  ready to be deployed to OC4J.
  • how-to-use-activemq-JCA-RA / build - temporary directory created during the build
  • how-to-use-activemq-JCA-RA / log - temporary directory holding build/deploy logs
  • how-to-use-activemq-JCA-RA / lib - holds the application archives that could be deployed (e.g., ear, war, rar, jar files)

Configuring the Environment

howto.properties
  • oracle.home - the root directory of oracle installation.  Defaults to ORACLE_HOME env variable.
  • java.home -  the root directory of JDK installation.  Defaults to JAVA_HOME env variable.
  • oc4j.host - the hostname of the platform on which the OC4J instance is running.  Defaults to localhost.
  • oc4j.http.port - the port on which the OC4J HTTP listener is listening.  Defaults to 8888.
  • oc4j.admin.port  - the port on which the OC4J administration process is listening.  Defaults to 23791.
  • oc4j.admin.user - the name of the OC4J administrator.  Defaults to "admin".
  • oc4j.admin.password - the password for the OC4J administrator.  Defaults to "welcome".
          ActiveMQ Specific properties
  • activemq.port - the port on which the ActiveMQ administration process is listening.  Defaults to 61616.
  • activemq.core.jar - The name of the default activeMQ jar which comes complete with all the libraries required by ActiveMQ. In ActiveMQ 4.0.1 release this jar will be found in  %ACTIVEMQ_HOME%/incubator-activemq-4.0.1.jar. Defaults to incubator-activemq-4.0.1.jar for 4.0,.1 release
  • activemq.home - the root directory of ActiveMQ installation.  Defaults to ACTIVEMQ_HOME env variable. You can install ActiveMQ  4.0.1 ,  from here
%OC4J_HOME%/ant/bin

Starting the OC4J Instance

  • %OC4J_HOME%/bin/oc4j start

Note that the oc4j command expects the JAVA_HOME environment variable to point to a full JDK installation.

Starting the ActiveMQ Instance

  • %ACTIVEMQ_HOME%/bin/activemq

Note that the activemq command expects the JAVA_HOME environment variable to point to a full JDK installation.

You need to install ActiveMQ 4by downloading the binaries from here.


Generating, Compiling , Deploying and Running the Application

Open a new console window. set the env variables ORACLE_HOME, ACTIVEMQ_HOME, JAVA_HOME as explained   here. To run the application, type the following command from the %HOWTO_HOME% directory:

  • ant

You should now have the newly created active-mq.ear in your %HOWTO_HOME%/lib directory.

This command would attempt to deploy the application if the build is successful. It will first test whether OC4J is running. After deploying it will also run the test .The test will execute the JMS client which will  post a message to the ActiveMQ inbound queue on which the MDB is listening via the ActiveMQ Resource Adapter

You should see this message on the console where you typed  ant.
" Sent message: Hello world to ActiveMQ inbound queue!"

Return to the console where you started OC4J and you will see output generated by the MDB and Stateless E JB.

"Inside MDB, received from inbound queue: Hello world to ActiveMQ inbound queue!
Message Received from MDB inside Session Bean: Hello world to ActiveMQ inbound queue!
Sending Message from Stateless EJB to ActiveMQ outbound queue: Hello world to ActiveMQ inbound queue!"

To verify if the message posted by Stateless EJB to the ActiveMQ outbound queue "queue.outbound"  was correctly received by ActiveMQ we will use  jconsole ( JMX Browser available by default with JDK15.

  • %JAVA_HOME/bin/jconsole. You will now see A Jconsole connect to agent window which will have a ActiveMQ process in the list . Select it  and hit Connect.
Jconsole Connect Image

  • Now go to the MBeans tab on the Jconsole. 
AtiveMQ MBean


  • You can now browse the queue.outbound  queue by using browse operation in "Operations" tab

ActiveMQ browse


  • The message send  by the Stateless Session Bean to the ActiveMQ outbound queue can be viewed by hitting the browse button. Please make sure to scroll to the end to see the text  message.

 

Note that you can also deploy the application separately . Ensure the %ORACLE_HOME% environment variable is defined, and from the %HOWTO_HOME% directory, type the command:

  • ant deploy

  • ant run

 

Simplified Steps:

  • In the first console window, start OC4J  using %OC4J_HOME%/bin/oc4j start
  • In the second console window start ActiveMQ using  %ACTIVEMQ_HOME%/bin/activemq
  • In the third console window. set the env variables ORACLE_HOME, ACTIVEMQ_HOME, JAVA_HOME as explained   here. cd   %HOWTO_HOME% and type ant . Make sure you have %ORACLE_HOME/ant/bin in your PATH
  • In the fourth console window. Type jconsole. You can use jconsole to verify if the outbound messages were received.

Summary

  • Known that OC4J 10g (10.1.3) fully supports JCA 1.5
  • Learned how to configure and use ActiveMQ Resource Adapter with OC4J for both inbound and outbound communication.
Left Curve
Popular Downloads
Right Curve
Untitled Document