JMS Transport

This document is all about the JMS (Java Messaging Service) Transport support in Apache Axis2, and how it should be configured.

Send your feedback or questions to: axis-dev@ws.apache.org. Prefix subject with [Axis2]. To subscribe to mailing list see here.

Overview

A new JMS or Java Messaging Service transport implementation has been added to Axis2 to overcome some drawbacks of the previous JMS implementation. Some of the enhancements provided with this new implementation is the ability to assign custom JMS destination names or existing JMS destinations to Axis2 services being deployed.

Configuration

To use the JMS transport, the axis2.xml configuration must be setup as follows in order to configure the JMSListener and the JMS Sender

    <transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
      <parameter name="default" locked="false">                
        <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
        <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>        
        <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
      </parameter>
    </transportReceiver>

    <transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender"/>

The JMS transport receiver configuration allows you to define the default connection factory (named as "default" ~ JMSConstants.DEFAULT_CONFAC_NAME) for use by Axis2 services using the JMS transport. This connection factory would be used by any service which does not explicitly specify a connection factory name in its services.xml. The configuration required to associate a (local) Axis2 connection factory to an actual implementation must be provided as shown above, to specify the JNDI URL, initial context factory class and the JNDI name of the actual JMS connection factory is to be used. You may also specify the parameters "java.naming.security.principal" and "java.naming.security.credentials" if required, to access the actual connection factory. The example shown above uses an ActiveMQ JMS implementation.

  <parameter name="myTopicConnectionFactory" locked="false">
    <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
    <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
    <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">TopicConnectionFactory</parameter>
  </parameter>

If it is required or applicable, you are free to define additional (local) connection factories to Axis2 as shown above, which your services may use. For a service to specify that such a connection factory should be used, its services.xml may specify the following configuration parameter:

services.xml  
  <parameter name="transport.jms.ConnectionFactory" locked="true">myTopicConnectionFactory</parameter>

Note: Depending on your JMS implementation, you will need to make available all required libraries to your Axis2 instance. This example assumes you are using an ActiveMQ instance. To run the given code samples, it was required to make available the following JAR files: activeio-core-3.0-beta1.jar, activemq-core-4.0-RC2.jar, geronimo-j2ee-management_1.0_spec-1.0.jar at a minimum. It also requires you to start ActiveMQ separately from Axis2, and then provide the appropriate configuration settings (e.g. URL) to Axis2.

During initialization, the JMS Listener creates a dedicated JMS message processor for each connection factory defined, and utilizes a shared thread pool to process received messages.

A service on an Axis2 instance is deployed on all started transports by default, unless a list of transports are specified in its services.xml. Hence, if a service must only be deployed on JMS, you should specify it on the services.xml as follows:

  <transports> 
    <transport>jms</transport> 
  </transports>

If the services.xml does not provide an explicit JMS destination name, it is assumed that the service will listen for messages on a JMS Queue by the same name as the name of the service. If an explicit connection factory definition name has not been specified, it is assumed that the "default" connection factory definition configured within the transport receiver be used. To provide a custom JMS destination name and connection factory, the services.xml could provide the following optional parameters.

  <parameter name="transport.jms.ConnectionFactory" locked="true">myTopicConnectionFactory</parameter>
  <parameter name="transport.jms.Destination" locked="true">dynamicTopics/something.TestTopic</parameter>

Writing Services to Use The JMS Transport

This section assumes that you are already familiar with writing service implementations for Axis2, and provides information to enable you to write your own service implementations which are exposed over JMS.

Echo - Service implementation and services.xml

This sample demonstrates a very simple service which is to be exposed over JMS. It does not specify a custom connection factory name and hence uses the "default" as specified in the JMS transport listener configuration. It also does not specify a custom destination name, and hence would listen to messages over a JMS Queue named "Echo" (which is the name of the service). This service will be exposed over all defined Axis2 transports, and the resulting URL for the service over JMS would be:

jms:/echo?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616

  public class Echo {
    public String echoString(String in) {
      return in;
    }
    public String echoString1(String in) {
      return "echoString1 " + in;
    }
    public String echoString2(String in) {
      return "echoString2 " + in;
    }
  }


  <service name="echo">
    <description>Echo Service</description>
    <messageReceivers>
      <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
        class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
      <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
        class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
    </messageReceivers>
    <parameter name="ServiceClass" locked="true">Echo</parameter>
</service>

Echo2 - Service implementation and services.xml

This example shows a simple service which specifies that it should only be exposed over the JMS transport, and that the custom connection factory named "myTopcConnectionFactory" should be used to listen for requests at the JMS destination named "dynamicTopics/something.TestTopic". The JMS URL to access this service is:

jms:/dynamicTopics/something.TestTopic?transport.jms.ConnectionFactoryJNDIName=TopicConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&java.naming.security.principal=system&java.naming.security.credentials=manager

  public class Echo2 {
    public String echoString(String in) {
      return in;
    }
  }


  <service name="echo">
    <transports>
      <transport>jms</transport>
    </transports>
    <description>Echo2 Service</description>
    <messageReceivers>
      <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
        class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
      <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
        class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
    </messageReceivers>
    <parameter name="ServiceClass" locked="true">Echo2</parameter>
    <parameter name="transport.jms.ConnectionFactory" locked="true">myTopicConnectionFactory</parameter>
    <parameter name="transport.jms.Destination" locked="true">dynamicTopics/something.TestTopic</parameter>
  </service>
 

Starting up the Axis2 JMS transport

The Axis2 standalone binary distribution ships with an Axis2 Server, which starts up all of the transports that are configured as per the axis2.xml. 
Hence configure the JMS transport in your axis2.xml, and use the axis2server.bat or the axis2server.sh to start the JMS transport.