24.10. Configure a Generic JMS Resource Adapter for Use with a Third-party JMS Provider

Summary

JBoss EAP 6 can be configured to work with third-party JMS providers, however not all JMS providers produce a JMS JCA resource adapter for integration with Java application platforms. This procedure covers the steps required to configure the generic JMS resource adapter included in JBoss EAP 6 to connect to a JMS provider. In this procedure, Tibco EMS 6.3 is used as an example JMS provider, however other JMS providers may need a different configuration.

Important

The generic JMS JCA resource adapter should only be used when a JMS provider does not provide its own resource adapter. Before using the generic JMS resource adapter, you should first check with the JMS provider to see if they have their own resource adapter that can be used with JBoss EAP 6.
Prerequisites

This procedure assumes that a JMS provider server is already configured and ready for use. Any binaries required for the provider's JMS implementation will be needed. You will also need to know the values of the following JMS provider properties:

  • PROVIDER_HOST:PROVIDER_PORT: The host name and port number of the JMS provider server.
  • PROVIDER_CONNECTION_FACTORY: The name of the connection factory deployed on the JMS provider server. This must be XA.
  • PROVIDER_QUEUE, PROVIDER_TOPIC: The names of the queues and topics on the JMS provider server that are to be used.

Procedure 24.10. Configure a Generic JMS Resource Adapter

  1. Create an ObjectFactory implementation for the JNDI binding of queues and topics:
    1. Using the code below as a template, replace the server details with your JMS provider server values.
      import java.util.Hashtable;
      import java.util.Properties;
       
      public class RemoteJMSObjectFactory implements ObjectFactory {
       
        private Context context = null;
       
        public RemoteJMSObjectFactory() {
        }
       
        public Object getObjectInstance(Object obj, Name name, Context nameCtx,
            Hashtable<?, ?> environment) throws Exception {
          try {
            String jndi = (String) obj;
       
            final Properties env = new Properties();
            env.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.tibco.tibjms.naming.TibjmsInitialContextFactory");
            env.put(Context.URL_PKG_PREFIXES, "com.tibco.tibjms.naming");
            env.put(Context.PROVIDER_URL, "tcp://TIBCO_HOST:TIBCO_PORT");
       
            context = new InitialContext(env);
            Object o = context.lookup(jndi);
       
            return o;
          } catch (NamingException e) {
            e.printStackTrace();
            throw e;
          }
        }
      }
      
    2. Compile the above code, and save the resulting class file in a JAR file named remoteJMSObjectFactory.jar
  2. Create a genericjms module for your JBoss EAP 6 instance:
    1. Create the following directory structure: EAP_HOME/modules/system/layers/base/org/jboss/genericjms/provider/main
    2. Copy the remoteJMSObjectFactory.jar file to EAP_HOME/modules/system/layers/base/org/jboss/genericjms/provider/main
    3. Copy the binaries required for the provider's JMS implementation to EAP_HOME/modules/system/layers/base/org/jboss/genericjms/provider/main. For Tibco EMS, the binaries required are tibjms.jar and tibcrypt.jar from the Tibco installation's /lib directory.
    4. Create a module.xml file in EAP_HOME/modules/system/layers/base/org/jboss/genericjms/provider/main as below, listing the JAR files from the previous steps as resources:
      <module xmlns="urn:jboss:module:1.1" name="org.jboss.genericjms.provider"> 
        <resources> 
            <resource-root path="tibjms.jar"/> 
            <resource-root path="tibcrypt.jar"/>
            <resource-root path="remoteJMSObjectFactory.jar"/>
        </resources> 
      
         <dependencies> 
            <module name="javax.api"/> 
            <module name="javax.jms.api"/> 
        </dependencies> 
      </module>
  3. Add the generic JMS module as a dependency for all deployments as global modules.

    Note

    In this procedure, EAP_HOME/standalone/configuration/standalone-full.xml is used as the JBoss EAP 6 configuration file.
    In EAP_HOME/standalone/configuration/standalone-full.xml, under <subsystem xmlns="urn:jboss:domain:ee:1.1">, add:
    <global-modules>
      <module name="org.jboss.genericjms.provider" slot="main"/>
      <module name="org.jboss.common-core" slot="main"/>
    </global-modules>
  4. Replace the default HornetQ resource adapter with the generic resource adapter.
    In EAP_HOME/standalone/configuration/standalone-full.xml, replace <subsystem xmlns="urn:jboss:domain:ejb3:1.4"> <mdb>, with:
    <mdb>
      <resource-adapter-ref resource-adapter-name="org.jboss.genericjms"/>
      <bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
    </mdb>
  5. Add bindings for your JMS topics and queues as remote objects as necessary.
    In EAP_HOME/standalone/configuration/standalone-full.xml, under <subsystem xmlns="urn:jboss:domain:naming:1.3">, add the bindings, replacing PROVIDER_QUEUE and PROVIDER_TOPIC as necessary:
    <bindings>
      <object-factory name="PROVIDER_QUEUE" module="org.jboss.genericjms.provider" class="org.jboss.qa.RemoteJMSObjectFactory"/>
      <object-factory name="PROVIDER_TOPIC" module="org.jboss.genericjms.provider" class="org.jboss.qa.RemoteJMSObjectFactory"/>
    </bindings>
  6. In EAP_HOME/standalone/configuration/standalone-full.xml, add the generic resource adapter configuration to <subsystem xmlns="urn:jboss:domain:resource-adapters:1.1">.
    Replace PROVIDER_CONNECTION_FACTORY, PROVIDER_HOST, and PROVIDER_PORT with the JMS provider values.
    <resource-adapters>
      <resource-adapter id="org.jboss.genericjms">
        <module slot="main" id="org.jboss.genericjms"/>
        <transaction-support>NoTransaction</transaction-support>
        <connection-definitions>
          <connection-definition class-name="org.jboss.resource.adapter.jms.JmsManagedConnectionFactory" jndi-name="java:/jms/PROVIDER_CONNECTION_FACTORY" pool-name="PROVIDER_CONNECTION_FACTORY">
            <config-property name="JndiParameters">
              java.naming.factory.initial=com.tibco.tibjms.naming.TibjmsInitialContextFactory;java.naming.provider.url=tcp://PROVIDER_HOST:PROVIDER_PORT
            </config-property>
            <config-property name="ConnectionFactory">
              PROVIDER_CONNECTION_FACTORY
            </config-property>
            <security>
              <application/>
            </security>
          </connection-definition>
        </connection-definitions>
      </resource-adapter>
    </resource-adapters>
Result

The generic JMS resource adapter is now configured and ready for use.

When creating a new message driven bean (MDB), use code similar below to use the resource adapter. Replace PROVIDER_CONNECTION_FACTORY, PROVIDER_HOST, and PROVIDER_PORT with the JMS provider values.
Optionally, the example below also configures a secure connection for Tibco EMS by specifying the user and password properties (replace the property values as needed).
@MessageDriven(activationConfig = { 
  @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), 
  @ActivationConfigProperty(propertyName = "jndiParameters", propertyValue = "java.naming.factory.initial=com.tibco.tibjms.naming.TibjmsInitialContextFactory;java.naming.provider.url=tcp://PROVIDER_HOST:PROVIDER_PORT")
  @ActivationConfigProperty(propertyName = "destination", propertyValue = "PROVIDER_QUEUE"), 
  @ActivationConfigProperty(propertyName = "connectionFactory", propertyValue = "PROVIDER_CONNECTION_FACTORY"),
  @ActivationConfigProperty(propertyName = "user", propertyValue = "USER"),
  @ActivationConfigProperty(propertyName = "password", propertyValue = "PASSWORD"),
})

@ResourceAdapter("org.jboss.genericjms")
public class SampleMdb implements MessageListener { 
  @Override

    public void onMessage(Message message) { 
    
    } 

}