readStringOfCharLengthint length引发EOF异常

问题描述

我已经编写了下面的代码来读取IBM MQ中的多个消息

com.ibm.mq.MQQueue defaultLocalQueue;
        MQQueueManager qManager=null;
        
        MQEnvironment.hostname = "reese.int.westgroup.com";
        MQEnvironment.channel = "CLIENTCONNECTION";
        MQEnvironment.port = 1414;
        String qMngrStr = "";
        qManager = new MQQueueManager(qMngrStr); 
        int openoptions = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_OUTPUT | MQC.MQOO_INQUIRE ; 
        String queueName="COMSERV.SRCHEXT.EVENTS.PUBLISH.QA.Q01";
        System.out.println("accessing::"+queueName);
        defaultLocalQueue = qManager.accessQueue(queueName,openoptions);
        //set transport properties.
        System.out.println("set MQ props");
        MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY,MQC.TRANSPORT_MQSERIES_CLIENT);
        System.out.println("new Queuemanager");
        ArrayList<MQMessage> msg = new ArrayList<MQMessage>();
        //MQMessage putMessage = new MQMessage();
        //String msg = "hello";
       // putMessage.writeUTF(msg);
        
        //specify the message options...
       // MQPutMessageOptions pmo = new MQPutMessageOptions(); 
        // accept 
        // put the message on the queue
        //defaultLocalQueue.put(putMessage,pmo);
        boolean getMore = true;
        while(getMore)
        {  
        MQMessage getMessages= new MQMessage();
        MQGetMessageOptions gmo = new MQGetMessageOptions();
        gmo.options=MQC.MQGMO_WAIT;
        gmo.waitInterval=1000000;
        //gmo.wait(100000);

        System.out.println("get messages::"+gmo.toString());
        defaultLocalQueue.get(getMessages,gmo);
        
        msg.add(getMessages);
        int length=getMessages.getMessageLength();
        System.out.println("length::"+length);
        String retrievedMsg = getMessages.readStringOfCharLength(length);
        System.out.println("Message got from MQ: "+retrievedMsg);
       
        }
        if(defaultLocalQueue.getCurrentDepth()==0)
         {
            getMore=false;
         }
        for (MQMessage message : msg)
        {
            System.out.println("message::"+message);
            
        }
        }
        
  

String retrievedMsg = getMessages.readStringOfCharLength(length); 

即使消息在MQ中存在并且消息的长度也在打印3760,也会导致EOF异常。

下面是该异常的完整堆栈跟踪。

length::3760

    java.io.EOFException: MQJE086: End of file exception ('MQMessage.readChar()').
        at com.ibm.mq.MQMessage.readChar(MQMessage.java:908)
        at com.ibm.mq.MQMessage.readStringOfCharLength(MQMessage.java:1232)
        at com.tlr.searchextract.messages.MessageTrigger_ABean.init(MessageTrigger_ABean.java:109)
        at com.tlr.searchextract.servlet.SEControllerServlet.insertRequestTemplate(SEControllerServlet.java:1385)
        at com.tlr.searchextract.servlet.SEControllerServlet.performTask(SEControllerServlet.java:2055)
        at com.tlr.searchextract.servlet.SEControllerServlet.doPost(SEControllerServlet.java:117)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:203)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

请帮助我。

解决方法

MQ KnowLedge Center中的MQMessage:

getMessageLength()获取此消息数据的字节数 消息。

因此,一种方法以字节为单位,然后使用readStringOfCharLength方法以字符为单位。

仅供参考:字节长度!=字符长度

您应该使用readStringOfByteLength方法。

int length=getMessages.getMessageLength();
String retrievedMsg = getMessages.readStringOfByteLength(length);

更新时间:2020年8月19日。

如果MQ无法将消息转换为字符串,则可以将其作为字节数组获取,并让JVM尝试将其转换为字符串。

int length=getMessages.getMessageLength();
byte[] bMsg = new byte[length];
getMessages.readFully(bMsg);
String retrievedMsg = new String(bMsg);
,

这在Printing the content of a message using IBM® MQ classes for Java中有记录:

import com.ibm.mq.MQMessage;
import com.ibm.mq.headers.MQHeaderList;
...
MQMessage message = ... // Message received from a queue.

System.out.println (new MQHeaderList (message,true));