ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ Java / JMS » Problems getting multiple messages from a queue

Post new topic  Reply to topic Goto page 1, 2  Next
 Problems getting multiple messages from a queue « View previous topic :: View next topic » 
Author Message
KeithPark
PostPosted: Thu Jun 02, 2005 6:39 am    Post subject: Problems getting multiple messages from a queue Reply with quote

Apprentice

Joined: 12 Nov 2002
Posts: 25

Hi

I am trying to get 2 messages from a local queue.

On our unix box (AIX 5.1, MQ Series 5.3, JRE 1.4.2) the second message is corrupting the first.

However, when using a client connection from my desktop it runs fine, with both messages being extracted correctly. We have recently had this Unix box upgraded so that is where my major suspicion is pointing but not sure why it would not do it on the client.

Any suggestions gratefully recieved...

Thanks

Keith
Back to top
View user's profile Send private message
vennela
PostPosted: Thu Jun 02, 2005 6:51 am    Post subject: Reply with quote

Jedi Knight

Joined: 11 Aug 2002
Posts: 4055
Location: Hyderabad, India

Quote:
the second message is corrupting the first.

What do you mean corrupting?
How does your code look like
Back to top
View user's profile Send private message Send e-mail Visit poster's website
KeithPark
PostPosted: Thu Jun 02, 2005 7:02 am    Post subject: Reply with quote

Apprentice

Joined: 12 Nov 2002
Posts: 25

Hi

The code is as below and is looped through twice to get both messages:

See below for a the code for the complete method

I am sending 2 compressed files. When I look at the output the data from the second message appears to be overwriting the data from the first, but only up to the length of the first message - ie the second message is longer but when it replaces the first it is truncated to match the correct data length for the first.

Hope that makes some sort of sense.

Thanks

Keith


Last edited by KeithPark on Fri Jun 03, 2005 5:18 am; edited 1 time in total
Back to top
View user's profile Send private message
vennela
PostPosted: Thu Jun 02, 2005 7:07 am    Post subject: Reply with quote

Jedi Knight

Joined: 11 Aug 2002
Posts: 4055
Location: Hyderabad, India

Looks like you are instantiating the Message Object outside the loop instead of inside the loop. But unfortunately that part of code is not posted.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
KeithPark
PostPosted: Fri Jun 03, 2005 12:26 am    Post subject: Reply with quote

Apprentice

Joined: 12 Nov 2002
Posts: 25

Hi

Here is the code for the entire method, which as you can see has the message instantiated inside the loop:

Code:
    public synchronized void getMessages(Vector vMessages, int nTimeout) throws SourceException
    {
        //Clear vector
        vMessages.removeAllElements();

        for (int msg = 0; msg < msgsToRead; msg++)
        {

            try
            {
               MQMessage theMessage = new MQMessage();
 
               //Specify the get message options
               MQGetMessageOptions gmo = new MQGetMessageOptions();

               //Retrieve get message options from MQOptionsFactory
                gmo = MQOptionsFactory.getGetMessageOptions(context, sInstanceName);

                //Get the Message off the Queue
                mqInputQueue.get(theMessage,gmo);

                if (theMessage != null)
                {
                    // Read the messageId into a String.
                    String sMessageId = new String(theMessage.messageId);

                    //Add the mesage to the Vector
                    vMessages.addElement(theMessage);
                   
                    //Got message OK
                    logger.log(Severity.DEBUG, new LogFormatter(this, "getMessages",
                        sInstanceName + " got message <" + sMessageId + ">"), null);
                }
                else
                {
                    break;
                }
               
            }
            catch(FactoryException e)
            {
                logger.log(Severity.ERROR, new LogFormatter(this, "getMessages",
                    "<" + sInstanceName +
                    "> Could not get MQ get-Message-Options from MQOptionsFactory <"),e);
                 throw new SourceException("<" + sInstanceName +
                    "> Could not get MQ get-Message-Options from MQOptionsFactory >");
            }
            catch(Exception exe)
            {
                logger.log(Severity.ERROR, new LogFormatter(this, "getMessages",
                    "<" + sInstanceName +
                    "> Could not define MQMessage <"),exe);
                 throw new SourceException("<" + sInstanceName +
                    "> Could not define MQMessage >");
            }
            catch(MQException mqex)
            {
                if (mqex.reasonCode == 2033)
                {

                    logger.log(Severity.DEBUG, new LogFormatter(this, "getMessages",
                        "Queue <" + sMQQueueName + "> : Reason Code = " + mqex.reasonCode),
                          mqex);
                }
                else
                {
                    logger.log(Severity.ERROR, new LogFormatter(this, "getMessages",
                        "<" + sInstanceName +
                        "> Could not retrieve message from Queue : Reason Code = <" + mqex.reasonCode + ">"),mqex);


                    if(MQOptionsFactory.isExceptionMessageLevel(mqex))
                    {
                        throw new SourceMessageException(null,"<" + sInstanceName +
                        "> Could not retrieve message from Queue : ReasonCode = <" + mqex.reasonCode + ">");
                    }
                    else
                    {
                        throw new SourceException("<" + sInstanceName +
                        "> Could not retrieve message from Queue : ReasonCode = <" + mqex.reasonCode + ">");
                    }
                }

            }
        }
    }


The following get message options were set:
OptionsFactory.setOptionsUsingProperties - Set option Data.Wait = No.
OptionsFactory.setGetWaitInterval - Set option Data.WaitInterval = UNLIMITED.
OptionsFactory.setOptionsUsingProperties - Set option Data.Syncpoint = Yes.

The other point I have is that if the message was instantiated in the wrong place I would expect it to produce a corrupt output over the client as well as on the Unix box, which it is not.



Keith


Last edited by KeithPark on Fri Jun 03, 2005 5:17 am; edited 1 time in total
Back to top
View user's profile Send private message
fschofer
PostPosted: Fri Jun 03, 2005 1:11 am    Post subject: Reply with quote

Knight

Joined: 02 Jul 2001
Posts: 524
Location: Mainz, Germany

Hi,
where did you find this options ?

Quote:
The following get message options were set:
OptionsFactory.setOptionsUsingProperties - Set option Data.Wait = No.
OptionsFactory.setGetWaitInterval - Set option Data.WaitInterval = UNLIMITED.
OptionsFactory.setOptionsUsingProperties - Set option Data.Syncpoint = Yes.


Please take a look in the Using Java Handbook for the allowed variables of MQGetMessageOptions.

Greetings
Frank
Back to top
View user's profile Send private message Send e-mail
KeithPark
PostPosted: Fri Jun 03, 2005 5:14 am    Post subject: Reply with quote

Apprentice

Joined: 12 Nov 2002
Posts: 25

Hi

Quote:
where did you find this options ?


These are local interpretations of the Get Message Options - they may not be exactly as described in the manual in this code snippet but map back to the correct variables in another class. This basically say's we are using no wait, and syncpoint control, which unless I am reading things wrong is an acceptable combination.

Further investigation has confirmed that the problem is occuring when you have MQ Series server 5.3 installed & running a local queue manager on the same machine as the java is running on. It does not occur with MQ Series 5.2 or with a Client connection (although I cannot be sure which version of the Client we are using but that is possibly 5.2).

I now have a local copy of MQ Series running on my desktop and can see the first message being added to the Vector, and then as soon as the second message is taken from the queue the content of the first message in the vector is corrupted with data from the second message. That would indicate that despite instantiating a new instance of the MQMessage there is still references to the first instance being held & being updated.

Back to top
View user's profile Send private message
jefflowrey
PostPosted: Fri Jun 03, 2005 5:31 am    Post subject: Reply with quote

Grand Poobah

Joined: 16 Oct 2002
Posts: 19981

Quote:
That would indicate that despite instantiating a new instance of the MQMessage there is still references to the first instance being held & being updated.


And let's be clear. The thing that is doing this is your code, somehow.

You seem to be working with an inhouse API that has wrapped MQ. Is it possible that the MQMessage class your code is using is not the straight C++ MQMessage class?

You should try to simplify your code down to the basics - something that reads messages from a queue and sticks them into a vector. Try working with one of the sample programs.

Also, you are doing
Code:
for (int msg = 0; msg < msgsToRead; msg++)

This is a bad design. You should read the queue until the Get gives you a 2033. You should not inq the qdepth first.
_________________
I am *not* the model of the modern major general.
Back to top
View user's profile Send private message
KeithPark
PostPosted: Fri Jun 03, 2005 5:53 am    Post subject: Reply with quote

Apprentice

Joined: 12 Nov 2002
Posts: 25

Quote:
And let's be clear. The thing that is doing this is your code, somehow.


Accepted - and that is where I expect the fix to be but given that the code works with V5.2 then it would seem to indicate that something else has changed within MQ or the MQ java classes.

I am debugging the extended MQMessage to try & find why it is corrupting.

Quote:
This is a bad design


That may be the way it appears but our application requires a specific number of messages (which is not necessarily all the messages in the queue) so in the context we use it I don't think it is an unreasonable way to do things. The msgsToRead is not the qdepth.

Back to top
View user's profile Send private message
jefflowrey
PostPosted: Fri Jun 03, 2005 6:03 am    Post subject: Reply with quote

Grand Poobah

Joined: 16 Oct 2002
Posts: 19981

KeithPark wrote:
jefflowrey wrote:
This is a bad design


That may be the way it appears but our application requires a specific number of messages(which is not necessarily all the messages in the queue) so in the context we use it I don't think it is an unreasonable way to do things.





Also, oops on the C++. I forgot which forum I was in...

Since your code is explicitly creating a new MQMessage object, you should not be getting the same one everytime.

It seems odd, but can you try
Code:
vMessages.addElement((Object)theMessage);

_________________
I am *not* the model of the modern major general.
Back to top
View user's profile Send private message
KeithPark
PostPosted: Fri Jun 03, 2005 6:11 am    Post subject: Reply with quote

Apprentice

Joined: 12 Nov 2002
Posts: 25

Thanks for the suggestion, but no joy unfortunately...

Back to top
View user's profile Send private message
fjb_saper
PostPosted: Fri Jun 03, 2005 10:20 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

Don't know if it is relevant but :
KeithPark wrote:
// Read the messageId into a String.
String sMessageId = new String(theMessage.messageId);

This is not a good idea. Treat messageId and correlation.Id as byte[]
Anything else will come back to bite you in the ....

And remember the conversion from byte[] into String is quite unpredictable where non character values are used. You are probably better off using a toHexValue of the wrapper... (Integer.toHexValue())

Enjoy
Back to top
View user's profile Send private message Send e-mail
jefflowrey
PostPosted: Fri Jun 03, 2005 11:23 am    Post subject: Reply with quote

Grand Poobah

Joined: 16 Oct 2002
Posts: 19981

The following code works for me. You might test it on your system and see what it does.

Code:

package test;

import java.io.EOFException;
import java.io.IOException;
import java.util.Iterator;
import java.util.Vector;

import com.ibm.mq.MQC;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;

public class MessageListTester {

   public static void main(String[] args) {
      MessageListTester mst = new MessageListTester();
      mst.start();
   }

   public void start() {
      Vector v = new Vector();
      try {
         MQQueueManager qMgr = new MQQueueManager("");
         int openOptions = MQC.MQOO_INPUT_SHARED;

         MQQueue myQueue = qMgr.accessQueue("SYSTEM.DEFAULT.LOCAL.QUEUE",
               openOptions, null, null, null);
         MQGetMessageOptions gmo = new MQGetMessageOptions();
         gmo.options = MQC.MQGMO_WAIT | MQC.MQGMO_FAIL_IF_QUIESCING;
         boolean stop = false;
         while (!stop) {
            MQMessage myMessage = new MQMessage();
            try {
               myQueue.get(myMessage, gmo);
            } catch (MQException e) {
               System.out.println("MQ exception: CC = " + e.completionCode
                     + " RC = " + e.reasonCode);
               stop = true;
            }
            if (!stop) {
               v.addElement((Object) myMessage);
            }
         }

         myQueue.close();
         qMgr.disconnect();
      } catch (MQException e) {
         e.printStackTrace();
      }

      Iterator i = v.iterator();
      while (i.hasNext()) {
         MQMessage element = (MQMessage) i.next();
         String msgData;
         try {
            msgData = element.readStringOfCharLength(element
                  .getDataLength());
            System.out.println(msgData);
         } catch (EOFException e1) {
            e1.printStackTrace();
         } catch (IOException e1) {
            e1.printStackTrace();
         }
      }
   }
}


Note that this is built on v6, not v5.3. I think "readStringOfCharLength" is new for v6 - I'm not positive. I was going to use just "readString", but it told me it was deprecated. Again, I think only with v6.
_________________
I am *not* the model of the modern major general.
Back to top
View user's profile Send private message
KeithPark
PostPosted: Mon Jun 06, 2005 1:09 am    Post subject: Reply with quote

Apprentice

Joined: 12 Nov 2002
Posts: 25

Hi

I have tried your sample - with the readStringOfCharLength changed to readString - and still got the same corrupt result.

That was running on my desktop using a local queue manager.

Back to top
View user's profile Send private message
jefflowrey
PostPosted: Mon Jun 06, 2005 3:04 am    Post subject: Reply with quote

Grand Poobah

Joined: 16 Oct 2002
Posts: 19981

When I ran my test, I put ten messages holding an integer (0 to 9! ) on SYSTEM.DEFAULT.LOCAL.QUEUE, first. I got 9 to 0 on the console as output, and a 2033 error.

I would open a PMR with IBM.

You aren't, by the way, using the MA88 Java classes with 5.3, are you? You should be using the versions that come with the 5.3 install.
_________________
I am *not* the model of the modern major general.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » IBM MQ Java / JMS » Problems getting multiple messages from a queue
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.