3
votes

My code is listening to an IBM MQ. Receives JMS BytesMessage, converts it to string in the receiver class and pass on the same JMS BytesMessage to another processor class. Processor class again converts it into String. Both receiver class and processor class use the same code like below to get the string from BytesMessage. I am getting the right string in the Receiver class but when trying to get the string from the BytesMessage in Processor class its returning empty string. Please advise what has to be done in addition to preserve the JMS BytesMessage so that it gets converted to String in the Processor class as well.

Code that sends message to processor:

String strMessage = null;
strMessage = getStringFromMessage(Message message)
process(message)

Code used for String Conversion:

if (message instanceof BytesMessage){
 BytesMessage byteMessage = (BytesMessage) message;
 byte[] byteData = null;
 byteData = new byte[(int) byteMessage.getBodyLength()];
 byteMessage.readBytes(byteData);
 stringMessage =  new String(byteData);
}
2

2 Answers

5
votes

I found the solution. I added the below code after reading the message for the first time

byteMessage.reset()

This has reset the cursor position to the beginning and hence i am able to read it in the processor. So my final code in the receiver will look like below

if (message instanceof BytesMessage){
BytesMessage byteMessage = (BytesMessage) message;
byte[] byteData = null;
byteData = new byte[(int) byteMessage.getBodyLength()];
byteMessage.readBytes(byteData);
byteMessage.reset();
stringMessage =  new String(byteData);
}

The reason to read it again is the i started reading it in the receiver to perform some recovery functionality. I wanted to implement that without touching the framework. Initial framework is to read the message only in the processor.

0
votes

The answer from @Shankar Anand will work but, I would like to refactor the code to accommodate what it exactly needs to do

 public String readIbmMqMessageAsString(BytesMessage message) throws JMSException, UnsupportedEncodingException {
        message.reset(); //Puts the message body in read-only mode and repositions the stream of bytes to the beginning
        int msgLength = ((int) message.getBodyLength());
        byte[] msgBytes = new byte[msgLength];
        message.readBytes(msgBytes, msgLength);
        String encoding = message.getStringProperty(JMS_IBM_CHARACTER_SET);
        return new String(msgBytes, encoding).trim();
    }

  1. Before reading the message, we need to reposition the stream of bytes to the beginning. Hence the message.reset() should happen before the actual reading of the message.
  2. Then we can read the message and put it in the bytes array
  3. When we create the String from the bytes, It's better to provide the encoding character set which character set is used in convert message to bye
  4. We may not need the extra trailing spaces. In that case, you can trim it as well.
  5. I throw the exceptions to the parent method to handle