从java程序向队列写入消息时Websphere MQ问题

时间:2016-07-25 09:13:54

标签: java ibm-mq mq

我正在尝试从Java程序向Queue发送消息,我遇到一个问题,它说它无法连接到主机&它似乎无法读取频道。

以下是来自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.

这是java代码,

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!");
    }

}

我正在尝试从命令行中读取队列中的消息,

./amqsget CSBTS.DEAL CSBTS.QUEUE.MANAGER

我无法弄清楚问题是什么,是连接还是通道。 P.S我的频道验证被禁用。

2 个答案:

答案 0 :(得分:2)

哼哼,从哪里开始?

(1)这是一些糟糕的代码。您的问题不是渠道或凭据,而是您缺乏代码。即使您没有意识到这一点,您的代码实际上也会从队列中放入并检索消息。 MQ日志中出现错误消息的原因是因为队列管理器将WTF表示为您的代码。编程101,如果连接到它,则断开连接。如果您打开它,请在完成后关闭它。不要懒惰,并假设别的东西会清理你的垃圾。因此,日志消息的原因是因为您没有关闭并断开与队列管理器的连接,并且它说WTF。

(2)不要使用MQEnvironment类,而是将连接信息放在Hashtable中并将其传递给MQQueueManager类。 MQEnvironment不是线程安全的。

(3)如果你想在MQGET上匹配MsgID和/或CorrelID,那么你实际上必须告诉队列管理器(参见下面的' gmo.matchOptions')。

(4)添加' FAIL_IF_QUIESCING'所有MQ API调用的选项 - 良好的编程实践。

这里更新了您的代码,以便队列管理器不会说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!");
   }
}

答案 1 :(得分:0)

Harsha,在代码中MQ连接没有断开连接。你能检查一下QueueManager上的MQ Disconnect是否有帮助吗? (https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.javadoc.doc/WMQJavaClasses/com/ibm/mq/MQQueueManager.html

您也可以获得有关此MQSeries线程的更多见解(http://www.mqseries.net/phpBB2/viewtopic.php?t=60349&sid=7370d64b1edf8d305e8e6e980ea423e0),您会发现该错误是因为应用程序未与QM正确断开连接。