As promised in our previous article we have come up with the configuration from JBoss AS 5.1 side which would help everyone to consume messages from Websphere MQ 7 which is residing on a remote box. In this article we will see how can one send messages (i.e. using a JAVA standalone code) to a remote queue on Box-1 having Websphere MQ 7 and those messages can be received by the consumer (i.e. using EJB3 MDB deployed on JBoss) from Box-2 which is a very basic scenario in most of the people.

The main concept for this is that we would be sending messages to the remote queue of Websphere MQ 7 on box-1 and on box-2 we would be creating a Websphere MQ provider which would have the URL and InitialContextFactory of the Websphere MQ having the queue on box-1 and using that Websphere MQ provider we would connect to the connection factory and would connect to the queue for Websphere MQ which is on box-1. Once we get the access of connection factory and queue we would just create an MDB which would using the Websphere MQ provider details and would be able to consume message from box-2 easily.

In Box-1 (10.10.10.10)

Lets say you have your Websphere MQ 7 running in this box and you can configure the remote queue in MQ 7 by following the steps given in the below article

Steps to Create A Remote Queue in WebSphere MQ 7

In Box-2 (20.20.20.20)

In this box we have a JBoss node called Node-1 and following things has to be done on this box.

Note: You would need the following jar files from Websphere MQ side to put in the /Node-1/lib directory

  • dhbcore.jar
  • mqcontext.jar
  • com.ibm.mq.jar
  • com.ibm.mqjms.jar
  • com.ibm.mq.pcf.jar
  • com.ibm.mq.jmqi.jar
  • com.ibm.mq.headers.jar
  • com.ibm.mq.commonservices.jar

.

  1. Put the “wsIBMmq-provider-service.xml” file in the “Node-1/deploy” folder
  2. wsIBMmq-provider-service.xml

    <server>
     <mbean code="org.jboss.jms.jndi.JMSProviderLoader" name="jboss.jms:service=JMSProviderLoader,name=WSIBMMQJMSProvider">
     <attribute name="ProviderName">WSIBMMQJMSProvider</attribute>
     <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
    <!-- Connection Factories name created on MQ, "JMS Administered Objects => <IP_ADDRESS>:<PORT>/<CHANNELS_NAME> => Connection Factoiries => <CONNECTION_FACTOIRIES_NAME> "-->
     <attribute name="FactoryRef">MyRemoteMQMgr</attribute>
     <attribute name="QueueFactoryRef">MyRemoteMQMgr</attribute>
     <attribute name="TopicFactoryRef">MyRemoteMQMgr</attribute>
     <attribute name="Properties">
          java.naming.factory.initial=com.ibm.mq.jms.context.WMQInitialContextFactory
          java.naming.provider.url=10.10.10.10:1415/MyRemoteChannel
          java.naming.security.authentication=none
     </attribute>
     </mbean>
     </server>
    

    Note: In “wsIBMmq-provider-service.xml” file you have to change the 10.10.10.10 with the your remote server name/IP address of the remote server on which MQ 7 is running and same goes for 1415 and MyRemoteChannel.

  3. Put the “MDB_30.ear” files in the “Node-1/deploy” folder
    1. Create a folder called “MDB_30.ear
    2. Under it create 2 folders called “MDB_30.jar” and “META-INF
    3. Inside “META-INF” create a “application.xml” file and update this file with the below details
    4. <?xml version="1.0" encoding="UTF-8"?>
      <application version="5" xmlns="http://java.sun.com/xml/ns/javaee"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                    http://java.sun.com/xml/ns/javaee/application_5.xsd">
         <module>
             <ejb>MDB_30.jar</ejb>
         </module>
      </application>
      
    5. Inside “MDB_30.jar” create a “MyMDB.java” file and update this file with the below details
    6. import javax.ejb.MessageDriven;
      import javax.jms.JMSException;
      import javax.jms.Message;
      import javax.jms.MessageListener;
      import javax.jms.TextMessage;
      import javax.ejb.ActivationConfigProperty;
      
      @MessageDriven(
          activationConfig={
              @ActivationConfigProperty(propertyName="providerAdapterJNDI", propertyValue="WSIBMMQJMSProvider"),
              @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
              @ActivationConfigProperty(propertyName="destination", propertyValue="MyRemoteQueue"),  
              @ActivationConfigProperty(propertyName="useDLQ", propertyValue="false"),
      	@ActivationConfigProperty(propertyName="reconnectAttempts", propertyValue="60"),
      	@ActivationConfigProperty(propertyName="reconnectInterval", propertyValue="10")
          }
      )
      
      public class MyMDB implements MessageListener{
      
          public void onMessage(Message message) {
              TextMessage textMessage = (TextMessage) message;
              try {
                  System.out.println("nnt Message Received by MDB : "+ textMessage.getText());
              } catch (JMSException e) {
                  e.printStackTrace();
              }
          }
      }
      
    7. Once every thing has been put at its place, then you compile the MyMDB.java code and if you want then you can also create an EAR archive file for above folder
  4. After following the above given steps, we have successfully configured all the setting from JBoss end. Now its time to test our configuration by following the below steps.

    Testing

    1. Create a Directory somewhere in your file system like: “/urs/JBoss/JBM/Queue” to write the QueueSend.java and as we have an MDB we would not need a QueueReceive.java programs.
    2. In QueueSend.java copy the below program
      import java.io.*;
      import java.io.*;
      import java.util.Hashtable;
      import javax.jms.JMSException;
      import javax.jms.Queue;
      import javax.jms.QueueConnection;
      import javax.jms.QueueConnectionFactory;
      import javax.jms.QueueSender;
      import javax.jms.QueueSession;
      import javax.jms.Session;
      import javax.jms.TextMessage;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      
      public class QueueSend
      {
      public final static String JNDI_FACTORY="com.ibm.mq.jms.context.WMQInitialContextFactory";
      
      //*************** Connection Factory JNDI name *************************
      public final static String JMS_FACTORY="MyRemoteMQMgr"; 
      
      //*************** Queue Factory JNDI name *************************
      public final static String QUEUE="MyRemoteQueue";
      
      
      private QueueConnectionFactory qconFactory;
      private QueueConnection qcon;
      private QueueSession qsession;
      private QueueSender qsender;
      private Queue queue;
      private TextMessage msg;
      
      public void init(Context ctx, String queueName)throws NamingException, JMSException
      {
      qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
      qcon = qconFactory.createQueueConnection();
      qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
      queue = (Queue) ctx.lookup(queueName);
      qsender = qsession.createSender(queue);
      msg = qsession.createTextMessage();
      qcon.start();
      }
      
      public void send(String message) throws JMSException {
      msg.setText(message);
      qsender.send(msg);
      }
      
      public void close() throws JMSException {
      qsender.close();
      qsession.close();
      qcon.close();
      }
      
      public static void main(String[] args) throws Exception {
      if (args.length != 1) {
      System.out.println("Usage: java QueueSend URL");
      return;
      }
      InitialContext ic = getInitialContext(args[0]);
      QueueSend qs = new QueueSend();
      qs.init(ic, QUEUE);
      readAndSend(qs);
      qs.close();
      }
      
      private static void readAndSend(QueueSend qs) throws IOException, JMSException
      {
      String line="Test Message Body with counter = ";
      BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
      boolean readFlag=true;
      System.out.println("ntStart Sending Messages (Enter QUIT to Stop):n");
      while(readFlag)
      {
      System.out.print("<Msg_Sender> ");
      String msg=br.readLine();
      if(msg.equals("QUIT") || msg.equals("quit"))
      {
      qs.send(msg);
      System.exit(0);
      }
      qs.send(msg);
      System.out.println();
      }
      br.close();
      }
      
      private static InitialContext getInitialContext(String url) throws NamingException
      {
      Hashtable env = new Hashtable();
      env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
      env.put(Context.PROVIDER_URL, url);
      return new InitialContext(env);
      }
      }
      
    3. Now open just 1 – command prompt and run the “. ./setMQ_CLASSPATH.sh” by adding two DOTs separated by a single space, in both the prompts to set the Environment (PATH & CLASSPATH).
    4. Note: The same jar files shown above would be required here as well, hence change the path given in the below script under MQ_LIB

      setMQ_CLASSPATH.sh

      #!/bin/sh
      
      echo "Exporting CLASSPATH for IBM MQ...."
      
      MQ_LIB=/home/urs/Remote_MQ/lib
      
      export CLASSPATH=$CLASSPATH:$MQ_LIB/com.ibm.mq.commonservices.jar:$MQ_LIB/com.ibm.mq.headers.jar:$MQ_LIB/com.ibm.mq.jmqi.jar:$MQ_LIB/com.ibm.mq.pcf.jar:$MQ_LIB/com.ibm.mqjms.jar:$MQ_LIB/dhbcore.jar:$MQ_LIB/mqcontext.jar:$MQ_LIB/com.ibm.mq.jar:.:
      echo "====================================="
      echo "CLASSPATH =" $CLASSPATH
      echo "====================================="
      
    5. Then compile the QueueSend.java programs.
    6. Now run the code with the following command
    7. Prompt-1

      java QueueSend 10.10.10.10:1415/MyRemoteChannel
       

    Once everything is up and running properly you just have to send around few messages in “Prompt-1” and you would notice that those messages would be shown in shell on which the Node-1 is running which is on Box-2. Hence when you are sending a messages to the Websphere MQ 7 queue which is on Box-1 the same messages are been consumed by the MDB which is been deployed on Node-1 running on Box-2.

    If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.