0

I have recently started working with IBM MQ (v7.5) and currently working on a bridge like service for 2 way data transfer between MQ & another REST service I have.

By using standard APIs I am able to read and write messages without any issue. But the problem I am facing came when I started setting up MQRFH2 header to my messages. I must be doing some mistake while writing data with header because every time I am getting "End of file exception ('MQMessage.seek()')." error while reading those messages.

This is my code snippet while putting the message into MQ:

//Constructing message
MQMessage sendmsg = new MQMessage();
sendmsg.characterSet = 1208;
sendmsg.format = MQC.MQFMT_STRING;
sendmsg.feedback = MQC.MQFB_NONE;
sendmsg.messageType = MQC.MQMT_DATAGRAM;
sendmsg.replyToQueueName = outputBackupQueueName;
sendmsg.replyToQueueManagerName = queueManager;

//Constructing header
MQRFH2 rfh2 = new MQRFH2();
rfh2.setEncoding(MQConstants.MQENC_NATIVE);
rfh2.setCodedCharSetId(MQConstants.MQCCSI_INHERIT);
rfh2.setFormat(MQConstants.MQFMT_STRING);
rfh2.setNameValueCCSID(1208);

//adding message to header
rfh2.write(sendmsg);

//payload is the actual data which we want to send
byte[] messageBytes = payload.getBytes("UTF-8");
sendmsg.write(messageBytes);

//putting message to MQ
MQPutMessageOptions outputMsgOpt = new MQPutMessageOptions();
outputMsgOpt.options = MQConstants.MQPMO_FAIL_IF_QUIESCING |
                MQConstants.MQPMO_DEFAULT_CONTEXT |
                MQConstants.MQPMO_SYNCPOINT;

outputQueue.put(sendmsg, outputMsgOpt);
queueManager.commit();

And this is how I am trying to retrieve it later:

MQMessage incomingMessage = new MQMessage();
byte[] incomingMessageId = incomingMessage.messageId;
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQConstants.MQGMO_FAIL_IF_QUIESCING |
                        MQConstants.MQGMO_CONVERT |
                        MQConstants.MQGMO_SYNCPOINT |
                        MQConstants.MQGMO_LOGICAL_ORDER |
                        MQConstants.MQGMO_ALL_MSGS_AVAILABLE |
                        MQConstants.MQGMO_WAIT;

inputQueue.get(incomingMessage, gmo);
MQRFH2 myRfh2 = new MQRFH2(incomingMessage); //this statement throws error with headers

Complete error message is:

com.ibm.mq.headers.MQDataException: MQJE001: Completion Code '2', Reason '2195'.
    at com.ibm.mq.headers.MQDataException.getMQDataException(MQDataException.java:317)
    at com.ibm.mq.headers.internal.Header.read(Header.java:620)
    at com.ibm.mq.headers.MQRFH2.<init>(MQRFH2.java:113)
    at com.simility.util.MQRfh2HeaderHelper.getMsgByteArray(MQRfh2HeaderHelper.java:16)
    at com.simility.mq.SimilityMQBridge.main(SimilityMQBridge.java:182)

    Caused by: com.ibm.mq.headers.MQDataException: MQJE001: Completion Code '2', Reason '6114'.
    at com.ibm.mq.headers.MQDataException.getMQDataException(MQDataException.java:314)
    at com.ibm.mq.headers.MQRFH2.read(MQRFH2.java:184)
    at com.ibm.mq.headers.internal.Header.read(Header.java:639)
    at com.ibm.mq.headers.internal.Header.read(Header.java:617)
    ... 3 more

    Caused by: java.io.EOFException: MQJE086: End of file exception ('MQMessage.seek()').
    at com.ibm.mq.MQMessage.seek(MQMessage.java:716)
    at com.ibm.mq.headers.internal.store.MQMessageStore.readFrom(MQMessageStore.java:274)
    at com.ibm.mq.headers.internal.Header.read(Header.java:661)
    at com.ibm.mq.headers.MQRFH2.read(MQRFH2.java:181)

Another thing I verified is message length by "TotalMessageLength", and that matches between reading and writing the messages, but still the failure happens.

Can anyone please help me out or point me in right direction related to adding and retrieving messages with RFH2 header ?

JoshMc
  • 10,239
  • 2
  • 19
  • 38
0biwan
  • 31
  • 1
  • 8
  • Why do you want to manually setup and read a rfh2 headers? The attributes you are setting are already set in the MQMD. If you want to pass other properties use message properties that are naive in MQ since V7. – JoshMc Oct 08 '17 at 22:08
  • Thank you for replying. The complete payload structure given to me asks specifically to set RFH2 headers. As per this thread https://stackoverflow.com/questions/25906676/how-to-read-values-out-of-the-websphrere-mq-mqmd-header-with-the-ibm-mq-librarie even I realized about MQMD fields, but my clients are specifically asking to have message in this format. 1. MQMD 2. MQRFH2 3. Message-Body – 0biwan Oct 09 '17 at 04:02
  • Apparently it has something to do with PropertyControl of Queue. This blog dives deeper into the issue. http://www.capitalware.com/rl_blog/?p=1168 I am able to read the messages correctly if I simply ignore MQRFH2 headers. I will try with changing queue's propertyControl. But if anyone has faced this and figured out the resolution please do let me know. – 0biwan Oct 09 '17 at 09:27
  • You should not need to change the queue setting, the post you linked to from Roger, and the IBM Manual show you can add `MQConstants.MQGMO_PROPERTIES_FORCE_MQRFH2` to the get message options to accomplish the same thing. – JoshMc Oct 10 '17 at 16:24

1 Answers1

0

Another thing I verified is message length by "TotalMessageLength", and that matches between reading and writing the messages, but still the failure happens.

Does the method "getMessageLength()" of MQMessage return the data length of the payload?

Why don't you try (in the sender):

byte[] messageBytes = payload.getBytes();

If your data is not the same codepage or encoding then let MQ do the work rather than you doing getBytes("UTF-8").

i.e. Set the Encoding and CCSID to what the data is.

rfh2.setEncoding(???);
rfh2.setCodedCharSetId(???);
Roger
  • 7,062
  • 13
  • 20