2016-07-25 107 views
0

我想从Java程序中将消息发送到Queue,我遇到了一个问题,它说它无法连接到主机&看起来它不是能够阅读频道。从Java程序写入消息到队列时发生Websphere MQ问题

下面是从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 = "[email protected]"; 
    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我的频道身份验证已禁用。

+0

什么是你从Java命令得到的输出?我假设这不是您发布的第一组输出结果? – ipsi

+1

1.请发布运行程序时得到的异常堆栈跟踪。我们需要知道MQ原因码。 2.尝试获取您要连接的队列管理器的AMQERR01.log,为什么连接终止的关键信息位可能在那里。如果根本没有关于连接的信息,那么也许你使用的是错误的端口并且根本不连接到MQ。 3.尝试使用MQ示例连接到队列管理器,运行amqsput(samples/bin目录中的一个),看看会发生什么。 –

回答

0

Harsha,在代码中MQ Connection没有断开连接。你能否检查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断开连接。

2

Hummmm,从哪里开始?

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

谢谢@Roger的回答,这很有帮助。但我设法通过删除get部分来实现我的代码工作,我的实际需求只是将其放入队列中。 – Harsha

+0

确保您更新您的代码以匹配我所做的评论和我提供的代码示例。 – Roger