0

I want to resend a Message from a Dead Letter Queue. For that, I need to convert the Dead Letter to a BytesMessage (Payload could be a ZIP or a String).

What I tried so far:

Get RFH2 by MQRFH2 class and seek():

        mqMessage.seek(0); MQRFH2 rfh2 = new MQRFH2(mqMessage); byte[]
        data = new byte[mqMessage.getDataLength()];
        mqMessage.readFully(data); System.out.println("Message data: "
        +new String(data));.

Get RFH2 by MQHeaderlist:

        MQHeaderList list = new MQHeaderList (mqMessage, true); // Step 1.
        MQDLH dlh = (MQDLH) list.get (0); // Step 2.
        int reason = dlh.getReason (); // Step 3.
        list.remove (dlh); // Step 4.
        mqMessage = new MQMessage ();
        list.write (mqMessage, true); // Step 5.
        mqMessage.format = list.getFormat (); // Step 6.

        MQHeaderIterator it = new MQHeaderIterator(mqMessage);

        while (it.hasNext()) {
            MQHeader header = it.nextHeader();

            System.out.println("Header type " + header.type() + ": " + header);
        }

Get RFH2 by MQRFH2 class:

        MQHeader header = new MQRFH2(mqMessage);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        header.write(new DataOutputStream(out), CMQC.MQENC_NATIVE,
        CMQC.MQCCSI_DEFAULT); byte[] bytes = out.toByteArray(); String
        sout = new String(bytes); System.out.println(sout);

Nothing worked for me: I get errors, like this one:

MQJE001: Beendigungscode '2', Ursache '6114'.
MQJE001: Beendigungscode '2', Ursache '2195'.
ch.coop.mid.hecol.DAEQHandler.exception.ZDAEQException: com.ibm.mq.headers.MQDataException: MQJE001: Beendigungscode '2', Ursache '2195'.
    at ch.coop.mid.hecol.DAEQHandler.bl.impl.ZMQQueueImpl.resendAllLetters(ZMQQueueImpl.java:52)
    at ch.coop.mid.hecol.DAEQHandler.ZStart.main(ZStart.java:20)
Caused by: com.ibm.mq.headers.MQDataException: MQJE001: Beendigungscode '2', Ursache '2195'.
    at com.ibm.mq.headers.MQDataException.getMQDataException(MQDataException.java:316)
    at com.ibm.mq.headers.internal.Header.read(Header.java:620)
    at com.ibm.mq.headers.MQRFH2.<init>(MQRFH2.java:113)
    at ch.coop.mid.hecol.DAEQHandler.dto.ZMessageDTO.<init>(ZMessageDTO.java:60)
    at ch.coop.mid.hecol.DAEQHandler.bl.impl.ZMQQueueImpl.resendAllLetters(ZMQQueueImpl.java:50)
    ... 1 more
Caused by: com.ibm.mq.headers.MQDataException: MQJE001: Beendigungscode '2', Ursache '6114'.
    at com.ibm.mq.headers.MQDataException.getMQDataException(MQDataException.java:313)
    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)
    ... 4 more
Caused by: java.io.EOFException: MQJE086: Ausnahmebedingung durch Dateiende ('MQMessage.seek()').
    at com.ibm.mq.MQMessage.seek(MQMessage.java:715)
    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)

Is there another way to convert a Dead Letter to a BytesMessage without splitting the whole messages in to little parts an assembling them back together? This way is not very beautiful for my opinion. It's very unstable.

EDIT: I can only use the version 7.5.0.0 of the mq libraries in java.

toxerli
  • 17
  • 8
  • Why are you not using the dead letter handler to resend messages? You can set up rules to retry, forward, etc. See these 2 links for more info http://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.pla.doc/q005540_.htm http://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.ref.adm.doc/q083420_.htm – ValerieLampkin Jun 23 '16 at 19:33
  • Because I need to solve the "problem" with a java application. @ValerieLampkin – toxerli Jul 11 '16 at 11:18

1 Answers1

1

What in the world are you doing? You seem like you are attacking the problem backwards. The message layout is MQDLH + MQRFH2 + message data.

I'll assume you want to resend the "MQRFH2 + message data" to the original destination queue.

Here is how your code should look:

mqMsg.seek(0);
MQDLH dlh = new MQDLH(mqMsg);
System.out.println("Reason code= "+dlh.getReason() + " : Dest. Queue Name="+dlh.getDestQName());

byte[] bData = new byte[mqMsg.getDataLength()];
mqMsg.readFully(bData);

// Open the original destination queue
int openOutputOptions  = CMQC.MQOO_OUTPUT + CMQC.MQOO_FAIL_IF_QUIESCING;
MQQueue outQ = _qMgr.accessQueue( dlh.getDestQName().trim(),
                                  openOutputOptions,
                                  dlh.getDestQMgrName().trim(),
                                  null,
                                  null );

// Create a new message and set the values from DLH
MQMessage newMsg = new MQMessage();
newMsg.characterSet = dlh.getCharacterSet();
newMsg.encoding     = dlh.getEncoding();
newMsg.format       = dlh.getFormat();

newMsg.write(bData);  // write the data

MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.options =  CMQC.MQPMO_FAIL_IF_QUIESCING;

// Put the message to the destination queue
outQ.put(newMsg, pmo);

outQ.close();
Roger
  • 7,062
  • 13
  • 20