简体   繁体   中英

Websphere MQ issue while writing a message to queue from java program

I am trying to put a message to Queue from a Java program, I am getting an issue where it says it unable to connect to the host & it seems it is not able to read the channel.

Here is the error from AMERR01.log

----- amqccita.c : 4113 -------------------------------------------------------
07/25/2016 07:04:29 AM - Process(18280.26) User(mqm) Program(amqrmppa)
                    Host(ip-10-0-0-238) Installation(Installation1)
                    VRMF(8.0.0.4) QMgr(CSBTS.QUEUE.MANAGER)

AMQ9209: Connection to host 'ip-10-0-0-238 (10.0.0.238)' for channel 'CHAN2'
closed.

EXPLANATION:
An error occurred receiving data from 'ip-10-0-0-238 (10.0.0.238)' over TCP/IP.
 The connection to the remote host has unexpectedly terminated.

The channel name is 'CHAN2'; in some cases it cannot be determined and so is
shown as '????'.
ACTION:
Tell the systems administrator.

Here is the java code,

package com.sample.mq.client.ClientMQ;

import java.io.IOException;

import com.ibm.mq.MQC;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;

/**
 * Java class to connect to MQ. Post and Retreive messages.
 *
 */
public class MQClientTest {

    String qMngrStr = "CSBTS.QUEUE.MANAGER";
    String user = "mqm";
    String password = "bts@2016";
    String queueName = "CSBTS.DEAL";
    String hostName = "10.0.0.238";
    int port = 1414;
    String channel = "CHAN2";
    //message to put on MQ.
    String msg = "Hello World, WelCome to MQ.";
    //Create a default local queue.
    MQQueue defaultLocalQueue;
    MQQueueManager qManager;

    /**
     * Initialize the MQ
     *
     */
    public void init(){

        //Set MQ connection credentials to MQ Envorinment.
         MQEnvironment.hostname = hostname;
         MQEnvironment.channel = channel;
         MQEnvironment.port = port;
         MQEnvironment.userID = user;
         MQEnvironment.password = password;
         //set transport properties.
         MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);

         try {
             //initialize MQ manager.
            qManager = new MQQueueManager(qMngrStr);
        } catch (MQException e) {
            e.printStackTrace();
        }
    }

    /**
     * Method to put message to MQ.
     *
     */
    public void putAndGetMessage(){

        int openOptions = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_OUTPUT; 
        try {
            defaultLocalQueue = qManager.accessQueue(queueName, openOptions);

            MQMessage putMessage = new MQMessage();
            putMessage.writeUTF(msg);

            //specify the message options...
            MQPutMessageOptions pmo = new MQPutMessageOptions(); 
            // accept 
            // put the message on the queue
            defaultLocalQueue.put(putMessage, pmo);

            System.out.println("Message is put on MQ.");

            //get message from MQ.
            MQMessage getMessages = new MQMessage();
            //assign message id to get message.
            getMessages.messageId = putMessage.messageId;

            //get message options.
            MQGetMessageOptions gmo = new MQGetMessageOptions();
            defaultLocalQueue.get(getMessages, gmo);

            String retreivedMsg = getMessages.readUTF();
            System.out.println("Message got from MQ: "+retreivedMsg);

        } catch (MQException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

        System.out.println("Processing Main...");

        MQClientTest clientTest = new MQClientTest();

        //initialize MQ.
        clientTest.init();

        //put and retreive message from MQ.
        clientTest.putAndGetMessage();

        System.out.println("Done!");
    }

}

I am trying to read the message from the queue from the command line,

./amqsget CSBTS.DEAL CSBTS.QUEUE.MANAGER

I am not able to figure out what is the problem, is it with the connection or channel. PS My channel authentication is disabled.

Hummmm, where to begin?

(1) That's some bad code. Your problem is not the channel or credentials but rather your lack of code. Even though you don't realize it, your code actually, put and retrieved a message from a queue. The reason for the error message in the MQ log is because the queue manager said WTF to your code. Programming 101, if you connect to it, then disconnect from it. If you open it then close it when you are done. Don't be lazy and assume something else will clean up your garbage. Hence, the reason for the log message is because you did NOT close and disconnect from the queue manager and it said WTF.

(2) Don't use MQEnvironment class but rather put the connection information in a Hashtable and pass it to the MQQueueManager class. MQEnvironment is NOT thread safe.

(3) If you want to match on either MsgID and/or CorrelID on an MQGET then you actually have to tell the queue manager it (see 'gmo.matchOptions' below).

(4) Add the 'FAIL_IF_QUIESCING' options to all of your MQ API calls - good programming practice.

Here's your code updated so that the queue manager does NOT say WTF:

import java.io.IOException;
import java.util.Hashtable;

import com.ibm.mq.*;
import com.ibm.mq.constants.CMQC;

/**
 * Java class to connect to MQ. Post and Retrieve messages.
 * 
 * Sample Command Line Parameters 
 *  -h 127.0.0.1 -p 1414 -c TEST.CHL -m MQA1 -q TEST.Q1 -u userid -x password
 */
public class MQClientTest
{
   private Hashtable<String, String> params = null;
   private Hashtable<String, Object> mqht = null;
   private String qManager;
   private String inputQName;

   /**
    * The constructor
    */
   public MQClientTest()
   {
      super();
   }

   /**
    * Make sure the required parameters are present.
    * 
    * @return true/false
    */
   private boolean allParamsPresent()
   {
      boolean b = params.containsKey("-h") && params.containsKey("-p") &&
                  params.containsKey("-c") && params.containsKey("-m") &&
                  params.containsKey("-u") && params.containsKey("-x") &&
                  params.containsKey("-q");
      if (b)
      {
         try
         {
            Integer.parseInt((String) params.get("-p"));
         }
         catch (NumberFormatException e)
         {
            b = false;
         }
      }

      return b;
   }

   /**
    * Extract the command-line parameters and initialize the MQ variables.
    * 
    * @param args
    * @throws IllegalArgumentException
    */
   private void init(String[] args) throws IllegalArgumentException
   {
      params = new Hashtable<String, String>();
      if (args.length > 0 && (args.length % 2) == 0)
      {
         for (int i = 0; i < args.length; i += 2)
         {
            params.put(args[i], args[i + 1]);
         }
      }
      else
      {
         throw new IllegalArgumentException();
      }

      if (allParamsPresent())
      {
         qManager = (String) params.get("-m");
         inputQName = (String) params.get("-q");

         mqht = new Hashtable<String, Object>();

         mqht.put(CMQC.CHANNEL_PROPERTY, params.get("-c"));
         mqht.put(CMQC.HOST_NAME_PROPERTY, params.get("-h"));

         try
         {
            mqht.put(CMQC.PORT_PROPERTY, new Integer(params.get("-p")));
         }
         catch (NumberFormatException e)
         {
            mqht.put(CMQC.PORT_PROPERTY, new Integer(1414));
         }

         mqht.put(CMQC.USER_ID_PROPERTY, params.get("-u"));
         mqht.put(CMQC.PASSWORD_PROPERTY, params.get("-x"));

         // I don't want to see MQ exceptions at the console.
         MQException.log = null;
      }
      else
      {
         throw new IllegalArgumentException();
      }
   }

   /**
    * Method to put then get a message to/from a queue.
    */
   public void putAndGetMessage()
   {
      MQQueueManager qMgr = null;
      MQQueue        queue = null;
      MQMessage      putMessage = null;
      MQMessage      getMessage = null;

      int openOptions = CMQC.MQOO_INPUT_AS_Q_DEF | CMQC.MQOO_OUTPUT + CMQC.MQOO_FAIL_IF_QUIESCING;

      MQGetMessageOptions gmo = new MQGetMessageOptions();
      gmo.options = CMQC.MQGMO_NO_WAIT + CMQC.MQGMO_FAIL_IF_QUIESCING;

      MQPutMessageOptions pmo = new MQPutMessageOptions();
      pmo.options = CMQC.MQPMO_FAIL_IF_QUIESCING;

      String msg = "Hello World, WelCome to MQ.";

      try
      {
         qMgr = new MQQueueManager(qManager, mqht);
         queue = qMgr.accessQueue(inputQName, openOptions);

         putMessage = new MQMessage();
         putMessage.writeUTF(msg);

         // put the message on the queue
         queue.put(putMessage, pmo);

         System.out.println("Message is put on MQ.");

         // get message from MQ.
         getMessage = new MQMessage();
         // assign message id to get message.
         getMessage.messageId = putMessage.messageId;

         /*
          * Tell the queue manager that we want a message with a specific MsgID.
          */
         gmo.matchOptions = CMQC.MQMO_MATCH_MSG_ID;

         // get message options.
         queue.get(getMessage, gmo);

         String retreivedMsg = getMessage.readUTF();
         System.out.println("Message got from MQ: " + retreivedMsg);
      }
      catch (MQException e)
      {
         System.err.println("CC=" + e.completionCode + " : RC=" + e.reasonCode);
      }
      catch (IOException e)
      {
         e.printStackTrace();
      }
      finally
      {
         try
         {
            if (queue != null)
               queue.close();
         }
         catch (MQException e)
         {
            System.err.println("MQCLOSE CC=" + e.completionCode + " : RC="
                  + e.reasonCode);
         }

         try
         {
            if (qMgr != null)
               qMgr.disconnect();
         }
         catch (MQException e2)
         {
            System.err.println("MQDISC CC=" + e2.completionCode + " : RC="
                  + e2.reasonCode);
         }
      }
   }

   public static void main(String[] args)
   {
      System.out.println("Processing Main...");
      MQClientTest clientTest = new MQClientTest();

      try
      {
         // initialize MQ.
         clientTest.init(args);
         // put and retrieve message from MQ.
         clientTest.putAndGetMessage();
      }
      catch (IllegalArgumentException e)
      {
         System.out.println("Usage: java MQClientTest -h host -p port -c channel -m QueueManagerName -q QueueName -u userid -x password");
         System.exit(1);
      }

      System.out.println("Done!");
   }
}

Harsha , in the code the MQ Connection is not disconnected . Can you check if a MQ Disconnect on your QueueManager helps ? ( https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.javadoc.doc/WMQJavaClasses/com/ibm/mq/MQQueueManager.html )

You can get further insights on this MQSeries thread as well ( http://www.mqseries.net/phpBB2/viewtopic.php?t=60349&sid=7370d64b1edf8d305e8e6e980ea423e0 ) , you will find that the error is because applications have not disconnected properly from the QM.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM