Archive for June 2012

Configuring IBM MQ in JBoss


In today's post I will explain how to install the WebSphere MQ resource adapter on JBoss.

Installing WebSphere MQ resource adapter:
To install WebSphere MQ resource adapter, copy the file wmq.jmsra.rar (from installation directory) to the server's deploy directory, for example <install path>/server/default/deploy The resource adapter will be automatically picked up by the server.

Installing the WebSphere MQ Extended Transactional Client:
The WebSphere MQ Extended transactional client lets you use XA distributed transactions with CLIENT mode connections to a WebSphere MQ queue manager. To install it on JBoss, copy the file com.ibm.mqetclient.jar ( from installation directory ) to the server lib directory, for example <install path>/server/default/lib.

Configuring the resource adapter for your application:
The WebSphere MQ resource adapter lets you define a number of global properties. Resource definitions for outbound JCA flows are defined in a JBoss -ds.xml file named wmq.jmsra-ds.xml. The outline form of this file:

  
  
  
  



As can be seen above JCA connection factories are defined in the <tx-connection-factory> element and JMS queues and topics are defined as JCA administered object mbeans.

A complete example for our sample application defining two queues - inbound and outbound is given below:

    
        jms/MyAppConnectionFactory
        wmq.jmsra.rar
        true
        javax.jms.QueueConnectionFactory
        8
        36
        ${channel}
        ${hostName}
        1414
        ${queueManager}
        CLIENT
        munish
        JmsXARealm
        
    
    
  jms/IncomingQueue
  jboss.jca:name='wmq.jmsra.rar',service=RARDeployment
  javax.jms.Queue
  
   baseQueueManagerName=${queueManager}
   baseQueueName=MY.APP.INBOUND.QUEUE
    
    
    
        jms/OutgoingQueue
        jboss.jca:name='wmq.jmsra.rar',service=RARDeployment
        javax.jms.Queue
        
            baseQueueManagerName=${queueManager}
            baseQueueName=MY.APP.OUTBOUND.QUEUE
        
    



The place holder properties are defined in the JBoss start script as:
-Dchannel=MQTEST -DhostName=localhost -DqueueManager=TST_MGR

Configuring inbound message delivery:
Message delivery to a Message-Driven Enterprise JavaBean (MDB) is configured using a JBoss-specific file named jboss.xml, located in the MDB .ear file. The contents of this file will vary, but will be of the form:

jboss.xml:

 
  
   MyMessageBean
    
     
                     
                             DestinationType
                             javax.jms.Queue
                     
                     
                             destination
                             MY.APP.INBOUND.QUEUE
                     
                     
                             channel
                             ${channel}
                     
                     
                             hostName
                             ${hostName}
                     
                     
                             port
                             1414
                     
                     
                             queueManager
                             ${queueManager}
                     
                     
                             transportType
                             CLIENT
                     
                     
                             username
                             munish
                     
              
               
           wmq.jmsra.rar
     
 


The DestinationType and Name properties must be specified. Other properties are optional, and if omitted, take on their default values.

A simple MDB definition for the inbound message is shown below:
/**
 * This message driven bean is used to collect asynchronously received messages.
 *
 * @author Munish Gogna
 */
@MessageDriven(mappedName = "jms/IncomingQueue")
public final class MyMessageBean implements javax.jms.MessageListener {
  private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger.getLogger(MyMessageBean.class);
  public void onMessage(final javax.jms.Message message) {
    LOGGER.info("Received message: " + message);
    // TODO - do processing with the message here
  }
}


A plain java class to send message to the output queue is shown below.
/**
 * This class is used to send text messages to a queue.
 *
 * @author Munish Gogna
 */
public final class MessageSender {
  private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger.getLogger(MessageSender.class);
  /**
   * A coarse-grained method, nothing fancy. In actual applications please re factor the code and
   * handle the exceptions properly.
   *
   * @throws Exception
   */
  public void send(final String message) throws Exception {
    if (message == null) {
      throw new IllegalArgumentException("Parameter message cannot be null");
    }
    javax.jms.QueueConnection connection = null;
    javax.jms.Session session = null;
    try {
      javax.naming.Context fContext = new javax.naming.InitialContext();
      javax.jms.QueueConnectionFactory fConnectionFactory = (javax.jms.QueueConnectionFactory) fContext
          .lookup("java:jms/MyAppConnectionFactory");
      connection = fConnectionFactory.createQueueConnection();
      session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
      final javax.naming.Context jndiContext = new javax.naming.InitialContext();
      final javax.jms.Destination destination = (javax.jms.Destination) jndiContext.lookup("jms/OutgoingQueue");
      final javax.jms.MessageProducer messageProducer = session.createProducer(destination);
      final javax.jms.TextMessage textMessage = session.createTextMessage(message);
      messageProducer.send(textMessage);
      messageProducer.close();
    } catch (Exception nex) {
      throw nex;
    } finally {
      if (session != null) {
        try {
          session.close();
        } catch (JMSException e) {
          LOGGER.error("Failed to close JMS session", e);
        }
      }
      if (connection != null) {
        try {
          connection.close();
        } catch (JMSException e) {
          LOGGER.error("Failed to close JMS connection", e);
        }
      }
    }
  }
}
A utilty called RFHUTILC.EXE can be used to connect to remote queues.

That's all.
Monday, June 4, 2012
Posted by Munish Gogna

Popular Post

Labels

enums (1) java (2) JAX-RS (1) JPA (1) mysql (1) request 2 (1) RESTful (1) sphinx (1) tomcat (1) web service (2) ws (2)