Author |
Message
|
nzr1949 |
Posted: Wed Jul 27, 2005 9:01 am Post subject: Strange grouping issue |
|
|
Novice
Joined: 16 Nov 2004 Posts: 15
|
Hi,
I'm trying to place a set of messages onto a queue as a group, so they should all share the same groupId value and each should have an incrementing sequence value. I thought that I managed to get this working until the time came to pull the messages back off of the queue again. Instead of processing each of the messages in the group once and in order, my code gets stuck in the while loop and stays on the first message in the group. I didn't think that the problem was with this code so I inspected the 4 messages on the queue that I am trying to read and it seems that they all have different groupIds but incrementing sequence values. They also have the correct groupStatus values. Details of the 4 messages below:
Message number: 1
Group ID: [B@743399
Seq ID: 1
groupStatus: MQC.MQGS_MSG_IN_GROUP
Message number: 2
Group ID: [B@e7b241
Seq ID: 2
groupStatus: MQC.MQGS_MSG_IN_GROUP
Message number: 3
Group ID: [B@167d940
Seq ID: 3
groupStatus: MQC.MQGS_MSG_IN_GROUP
Message number: 4
Group ID: [B@1fae3c6
Seq ID: 4
MQC.MQGS_LAST_MSG_IN_GROUP
As you can see, everything seems correct except for the groupIds which are all different when they should be the same. Everything else, however, seems fine. How is this possible?
There are two code portions below, the first shows how I write the messages to the queue and the second is responsible for reading them off of the queue:
Code: |
qMgr = new MQQueueManager(qManager);
int openOptions = MQC.MQOO_INPUT_AS_Q_DEF
| MQC.MQOO_OUTPUT
| MQC.MQOO_INQUIRE
| MQC.MQOO_SET_IDENTITY_CONTEXT;
myQueue = qMgr.accessQueue(queue, openOptions,null,null,null);
File f = new File("Test.txt"); // file to break up and place onto the queue
FileInputStream fileInput = new FileInputStream(f);
int maxMsgSize = 0; // max size of a message (or portion of the file)
int fileSize = getFileSize(f);
// find out the max message size for the queue and queue manager
// and assign the smaller of these two values to maxMsgSize so I
// don't get a "message-too-big-for-queue" error
int queueManagerMaxMsgSize = qMgr.getMaximumMessageLength();
int queueMaxMsgSize = myQueue.getMaximumMessageLength();
if (queueManagerMaxMsgSize <= queueMaxMsgSize)
maxMsgSize = queueManagerMaxMsgSize;
else maxMsgSize = queueMaxMsgSize;
MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.options = MQC.MQPMO_LOGICAL_ORDER
| MQC.MQPMO_NEW_MSG_ID;
// Create message
MQMessage m = new MQMessage();
m.format = MQC.MQFMT_STRING;
m.messageFlags = MQC.MQMF_MSG_IN_GROUP; // set grouping
int counter = 0; // count how many bytes have been read in
int i = 0; // used to store a byte from the file
int messagesProcessedSoFar = 0; // number of messages placed on queue so far
// figure out how many messages the file will be broken up into
int noMessages = fileSize / maxMsgSize;
int remainder = fileSize % maxMsgSize;
if (remainder > 0) noMessages++;
System.out.println("predicted no of messages: " + noMessages);
while ((i = fileInput.read()) != -1)
{
// have reached maxMsgSize limit so put the message on the queue,
if (counter == maxMsgSize)
{
m.write(i); // write last byte
counter = 0; // reset counter for next message
myQueue.put(m,pmo);
// if this is last message
if (messagesProcessedSoFar == (noMessages - 1))
{
m.clearMessage(); // must do this or else file content from one
// message spills over into the next
m.messageFlags = MQC.MQMF_LAST_MSG_IN_GROUP;
}
else
{
m.clearMessage();
m.messageFlags = MQC.MQMF_MSG_IN_GROUP;
}
messagesProcessedSoFar++;
}
else
{
m.write(i);
counter++;
}
}
|
The above code works perfectly in terms of breaking up the file into the required number of mesages, I just don't seem to be grouping the messages properly.
Code: |
qMgr = new MQQueueManager(qManager);
int openOptions = MQC.MQOO_INPUT_AS_Q_DEF
| MQC.MQOO_OUTPUT
| MQC.MQOO_INQUIRE
| MQC.MQOO_BROWSE;
myQueue = qMgr.accessQueue(queue, openOptions,null,null,null);
MQMessage msg = new MQMessage();
MQGetMessageOptions ops = new MQGetMessageOptions();
ops.options = MQC.MQGMO_BROWSE_FIRST;
this.myQueue.get(msg, ops);
System.out.println("Group ID: " + msg.groupId);
System.out.println("Seq ID: " + msg.messageSequenceNumber);
if (ops.groupStatus == MQC.MQGS_MSG_IN_GROUP)
{
ops.matchOptions = MQC.MQMO_MATCH_GROUP_ID;
do
{
myQueue.get(msg, ops);
String s = msg.readString(msg.getMessageLength());
System.out.println(s);
} while (ops.groupStatus != MQC.MQGS_LAST_MSG_IN_GROUP);
}
|
In the above code, all that happens is that the do-while loop keeps printing the contents of the first message instead of going through all 4 messages. I believe this is to do with the fact that the groupIds are different and therefore when I tell the queue manager to read the next mesage in the group, it keeps accessing the same message because there is only one message with that particular groupId.
The problem must lie with my code that puts the messages onto the queue. Can anyone spot where I'm going wrong?
Thanks |
|
Back to top |
|
 |
jefflowrey |
Posted: Wed Jul 27, 2005 9:07 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Where do you explicitly assign the group id? _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Jul 27, 2005 11:49 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Are you treating the group ID as a String or as a byte[].
Remember if your message flow spans platforms with different CCSIDs the groupid will not get translated.
You have to treat the groupID as a byte Array
Enjoy |
|
Back to top |
|
 |
nzr1949 |
Posted: Wed Jul 27, 2005 12:25 pm Post subject: |
|
|
Novice
Joined: 16 Nov 2004 Posts: 15
|
Quote: |
Where do you explicitly assign the group id?
|
I haven't explicitly assigned the groupdId, the only reference to grouping is when I set the messageFlags to MQMF_MSG_IN_GROUP and MQC.MQMF_LAST_MSG_IN_GROUP. Is this something you have to do? From my understanding of the manuals I thought it's something that has a default value of 'NONE', meaning the queue manager assigns it a unique value if you don't specify one.
Quote: |
Are you treating the group ID as a String or as a byte[]
|
I only deal directly with groupId when I print it out to check its value. I don't think I'm messing about with it and causing it change (by mistakenly treating it as a String) with the way my code stands now.
I know the error lies in the first portion of code but I can't for the life of me spot what's causing it. I've gone through every thread there is on grouping and none of them have helped me solve this problem. Am I forgetting to set some option or messageFlag or call some function? Maybe I'm calling/setting one that I shouldn't be? If I'm not doing it properly then why are the sequence Ids of the 4 messages all fine? It doesn't make any sense that they are correctly numbered 1 - 4 in the right order yet as far as the queue manager is concerned none of the messages are part of a group. Surely they should all have a value of 1 if none of the messages are related. |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Jul 27, 2005 12:34 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Quote: |
I only deal directly with groupId when I print it out to check its value. |
Which way do you print it out.
Remember hex 00 is considered a string terminator in c
Enjoy  |
|
Back to top |
|
 |
nzr1949 |
Posted: Wed Jul 27, 2005 1:02 pm Post subject: |
|
|
Novice
Joined: 16 Nov 2004 Posts: 15
|
Taken from the second portion of code in my first post (reads grouped messages from queue):
Code: |
this.myQueue.get(msg, ops);
System.out.println("Group ID: " + msg.groupId);
System.out.println("Seq ID: " + msg.messageSequenceNumber);
|
|
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Jul 27, 2005 7:16 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
nzr1949 wrote: |
Taken from the second portion of code in my first post (reads grouped messages from queue):
Code: |
this.myQueue.get(msg, ops);
System.out.println("Group ID: " + msg.groupId);
System.out.println("Seq ID: " + msg.messageSequenceNumber);
|
|
From the manual Using Java:
Quote: |
groupId
public byte[] |
It is folly to believe that
Code: |
"Group ID:" + msg.groupId |
will give you any valid result. You will get the value of the memory indentifier...
See byte[].toString()....
You will have to find something else like displaying the hex value of every byte in the array
Enjoy  |
|
Back to top |
|
 |
nzr1949 |
Posted: Thu Jul 28, 2005 12:24 am Post subject: |
|
|
Novice
Joined: 16 Nov 2004 Posts: 15
|
Quote: |
You will have to find something else like displaying the hex value of every byte in the array
|
I did this and (lo and behold) all the groupIds now magically match:
Message number: 1
Group ID: 414D51205742524B5F514D202020202035D3E4422000CA02
Seq ID: 1
groupStatus: MQC.MQGS_MSG_IN_GROUP
Message number: 2
Group ID: 414D51205742524B5F514D202020202035D3E4422000CA02
Seq ID: 2
groupStatus: MQC.MQGS_MSG_IN_GROUP
Message number: 3
Group ID: 414D51205742524B5F514D202020202035D3E4422000CA02
Seq ID: 3
groupStatus: MQC.MQGS_MSG_IN_GROUP
Message number: 4
Group ID: 414D51205742524B5F514D202020202035D3E4422000CA02
Seq ID: 4
MQC.MQGS_LAST_MSG_IN_GROUP
Thanks for that suggestion fjb_saper, I now know that there's nothing wrong with my code that puts messages on the queue, I shall now divert my attention to the code that reads them off again as this is where the problem really lies. |
|
Back to top |
|
 |
nzr1949 |
Posted: Thu Jul 28, 2005 4:40 am Post subject: |
|
|
Novice
Joined: 16 Nov 2004 Posts: 15
|
Managed to find the problem: I wasn't specifying the GetMessage option
"MQC.MQGMO_LOGICAL_ORDER" in my code.
Thanks for everyone's help! |
|
Back to top |
|
 |
|