从Java读取MQ的所有消息时出现问题

时间:2018-07-09 06:54:41

标签: java ibm-mq

我已经开发了一个Java应用程序来从MQ读取消息。 Java应用程序必须从MQ中读取所有消息,然后将它们放入列表中并返回列表。我正在使用while循环逐个读取消息,如果发现2033异常并返回列表,则会中断消息。

我的问题是,阅读单个消息后出现2033异常。例如,我已将大约10条消息推入队列并运行我的应用程序,第一个循环读取了第一条消息并将其放入列表中。但是在第二个循环中,它在获取第二条消息时抛出2033年异常。然后,我需要运行该应用程序以读取第二条消息,并且发生同样的事情。

由于我是MQ的新手,所以找不到导致其发生的路由。我正在使用Java8和IBM MQ核心库。下面是我的代码。

package com.reciever.mq;


import com.ibm.mq.*;
import com.ibm.mq.constants.MQConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.*;


public class MQReceiver {

    private static final Logger LOGGER = LoggerFactory.getLogger(MQReceiver.class);

    private static int GET_OPTIONS_CONSTANT = MQConstants.MQGMO_WAIT |
    MQConstants.MQGMO_PROPERTIES_COMPATIBILITY |
    MQConstants.MQGMO_ALL_SEGMENTS_AVAILABLE |
    MQConstants.MQGMO_COMPLETE_MSG |
    MQConstants.MQGMO_ALL_MSGS_AVAILABLE |
    MQConstants.MQGMO_SYNCPOINT;

    public static MQQueueManager queueManager;

    public static void main(String[] args) throws MQException {

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

        mqOptions.put(MQConstants.HOST_NAME_PROPERTY, "host.name"); //just a placeHolder
        mqOptions.put(MQConstants.CHANNEL_PROPERTY, "channelName");
        mqOptions.put(MQConstants.USER_ID_PROPERTY, "userName");
        mqOptions.put(MQConstants.TRANSPORT_PROPERTY, MQConstants.TRANSPORT_MQSERIES);
        mqOptions.put(MQConstants.PORT_PROPERTY, 1980);

        queueManager = new MQQueueManager("queueManager", mqOptions);
        int options = MQConstants.MQOO_INPUT_AS_Q_DEF | MQConstants.MQOO_OUTPUT
        | MQConstants.MQOO_FAIL_IF_QUIESCING | MQConstants.MQOO_PASS_ALL_CONTEXT | MQConstants.MQOO_INQUIRE;

        MQQueue mq = queueManager.accessQueue("queueNametoRead", options);
        MQException.logExclude(2033);

        MQMessage mqMessage = new MQMessage();
        MQGetMessageOptions getOptions = new MQGetMessageOptions();
        getOptions.options = GET_OPTIONS_CONSTANT;
        getOptions.waitInterval = 1;

        //byte[] buffer = null;

        List<byte[]> msgList = new ArrayList<>();

        System.out.println("Current depth : " + mq.getCurrentDepth());

        boolean hasMsges = true;

        while(hasMsges){

            byte[] buffer = null;

            try{

                mq.get(mqMessage, getOptions);

                buffer = new byte[mqMessage.getDataLength()];
                mqMessage.readFully(buffer);

                queueManager.commit();

                System.out.println("Recieved Message....");
                msgList.add(buffer);

            } catch (MQException e) {
                if((e.completionCode == MQConstants.MQCC_FAILED) &&
                        (e.reasonCode == MQConstants.MQRC_NO_MSG_AVAILABLE)){
                    System.out.println(" No more messages.. : " + e.getReason());

                    break;
                }else if (e.getReason() != 2033) {
                    LOGGER.error("Error getting message from the queue: " + "", e);
                }
            } catch (IOException e) {
                LOGGER.error("Error reading the message from the queue: " + "", e);
            }
            /* finally {
            if(mq != null) mq.close();
                if(queueManager != null) queueManager.disconnect();
            }*/

        }

        System.out.println("Final List size : " + msgList.size());

    }

}

下面是我运行程序后的系统故障信息

Current depth : 9
Recieved Message...
 No more messages.. : 2033
Final List size : 1

从上面的输出中,它的打印电流深度为9。但是它在第二个循环中爆发。

2 个答案:

答案 0 :(得分:4)

从队列中获取消息时,将填充消息ID和相关ID字段。如果您使用相同的MQMessage来获取下一条消息,则必须首先重置这两个字段。因此,在调用get方法之前,请添加这两行。

 mqMessage.messageId     = MQConstants.MQMI_NONE;
 mqMessage.correlationId = MQConstants.MQCI_NONE;

答案 1 :(得分:0)

您还可以在循环内移动MQMessage对象的创建

 while(hasMsges){

            byte[] buffer = null;

            try{
                MQMessage mqMessage = new mqMessage();
                mq.get(mqMessage, getOptions);

这也将有助于解决问题