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 » Trouble w\JMSMessageID, JMSCorrelationID & message sele

Post new topic  Reply to topic Goto page 1, 2  Next
 Trouble w\JMSMessageID, JMSCorrelationID & message sele « View previous topic :: View next topic » 
Author Message
jonstrande
PostPosted: Thu Aug 29, 2002 5:41 am    Post subject: Trouble w\JMSMessageID, JMSCorrelationID & message sele Reply with quote

Newbie

Joined: 29 Aug 2002
Posts: 3
Location: Hershey PA

Hello all,

I am using MQ/JMS classes to send a message to a queue and then get a message out of the queue. The messages are being written to the 'IN' channel and read back out of an 'OUT' channel. Basically what we are doing is using MQ as a front end for our EIS systems. I post a message in the IN channel to MQ and MQ taskes the message, fulfills the request and puts the response in the OUT channel.

I need to make sure that I read the corresponding message in the OUT channel that is 'tied' to the message that I wrote to the IN channel.

I would like to use the getJMSCorrelationID, but that returns null, even if I set it to someting. I have tried getJMSMessageID but the response message doesn't seem to tie back to the original...

Here is my code - enclosed in a try/catch:
Code:

MQQueueConnectionFactory factory = new MQQueueConnectionFactory();
factory.setMethods()...

QueueConnection connection = factory.createQueueConnection();
if(connection != null){
    QueueSession  session = null;
    boolean transacted = false;
    System.out.println("calling createQueueSession()");
    session = connection.createQueueSession(transacted,   
                                  javax.jms.Session.AUTO_ACKNOWLEDGE);
    connection.start();
    System.out.println("calling createQueue() - in");

    Queue inQueue = session.createQueue(inQueueName);
    QueueSender queueSender = session.createSender(inQueue);
    System.out.println("calling createTextMessage()");
    Message message = session.createTextMessage();
    message.setStringProperty("testing", new java.util.Date().toString());
    System.out.println("calling send(message) ");
    message.setJMSCorrelationID("test");
    queueSender.send(message);
   
    String messageID = message.getJMSMessageID();
    System.out.println(messageID);
   
    System.out.println("calling createQueue() - out");
    Queue outQueue = session.createQueue(outQueueName);
    QueueReceiver queueReceiver = session.createReceiver
                                   (outQueue, "CorrelId = 'test'");

    QueueBrowser qb = session.createBrowser(outQueue);
    java.util.Enumeration e = qb.getEnumeration();
    System.out.println(" got browsableQueue");
    while(e.hasMoreElements()){
          Message queueMessage = (Message)e.nextElement();
          if(queueMessage != null){
             byte [] correlationID = 
                           queueMessage.getJMSCorrelationIDAsBytes();
             String stringID = "";
             for(int i =0; i < correlationID.length; i++){
                  stringID += Byte.toString(correlationID[i]);
              }
             System.out.print(stringID + " - " +
                    queueMessage.getJMSCorrelationID());
         }            
    }

    Message m = queueReceiver.receive(1000);
    if(m != null){
        TextMessage tm = (TextMessage)m;   
         if(tm != null){
             System.out.println("JMSMessageID=" + tm.getJMSMessageID());
             System.out.println("TimeStamp" + tm.getJMSTimestamp());
             String receiveString = tm.getText();
             System.out.println("Receive Message: " + receiveString);
         }
         else{
             System.out.println("tm is null");
         }
     }
     else{
           System.out.println("m is null");
     }
     queueSender.close();
     queueReceiver.close();
     session.close();
     connection.close();
     System.out.println("connection closed");
}


I DO NOT get back a correlation ID, even when I expressly set it.

Here is the output - I have several messages in there:
testing MQ connection...
calling createConnection()
calling createQueueSession()
calling createQueue() - in
calling createTextMessage()
calling send(message)
ID:414d51204d45525420202020202020203d6a49f8000dc012
calling createQueue() - out
got browsableQueue
000000000000000000000000 - null
000000000000000000000000 - null
000000000000000000000000 - null
000000000000000000000000 - null
000000000000000000000000 - null
000000000000000000000000 - null
000000000000000000000000 - null
000000000000000000000000 - null
000000000000000000000000 - null
calling queueReceiver.receive(1000)
m is null
connection closed


Thoughts? Comments? Suggestions?

Thank you in advance!

Jon
jstrande@hersheys.com
Back to top
View user's profile Send private message Visit poster's website Yahoo Messenger
jonstrande
PostPosted: Thu Aug 29, 2002 6:34 am    Post subject: Reply with quote

Newbie

Joined: 29 Aug 2002
Posts: 3
Location: Hershey PA

I got this working.

There are several things I was doing wrong, not the least of which was the fact that when the trigger ran on the IN channel, the CorrelId was not being carried forward to the message in the OUT channel.

Let me know if you want more information as to the resolution.

Jon
Back to top
View user's profile Send private message Visit poster's website Yahoo Messenger
middlewareonline
PostPosted: Sat Oct 05, 2002 11:11 am    Post subject: Reply with quote

Acolyte

Joined: 09 Jul 2001
Posts: 73

Could you please elaborate what changes you made to make it work.

I guess fex that I can tell is CorrID should have been JMSCorrelationID in selector and use hex code of the correlation id value. Also, correlation Id should be prefixed with "ID:" ( JMS standard).

Is there anything else that I am missing ?
Raj
Back to top
View user's profile Send private message Visit poster's website
jonstrande
PostPosted: Mon Oct 07, 2002 4:47 am    Post subject: Reply with quote

Newbie

Joined: 29 Aug 2002
Posts: 3
Location: Hershey PA

Raj,


Sure, here is what I did (This is sort of contact admin code, but you get the idea):

Code:

message.setJMSCorrelationID("12681"); //random number for testing
System.out.println(message.getJMSCorrelationID());
queueSender.send(message);
String testString = message.getJMSCorrelationID();
byte [] bytes = testString.getBytes();
StringBuffer sb = new StringBuffer();
for(int i = 0; i < bytes.length ; i++){
    sb.append(Integer.toHexString(bytes[i]));
}
int correlationIDLength = 48;
int zerosToFill = correlationIDLength - sb.length();
for(int i = 0; i < zerosToFill; i++ ){
    sb.append("0");
}
QueueReceiver queueReceiver = session.createReceiver(inQueue,
        "JMSCorrelationID = 'ID:"+sb.toString()+"'");


What I did was move all my MQ code into a 'MQService' class and hide the details from the user. So there is currently only one public method:
Code:

 public String sendMessage(String messageContent)


This works since we are sending XML through MQ and the XML is a string based representation of the XML. Inside the MQService class I create the Correlation ID for the user and take care of all the communication details for them.

Hope this helps!

Jon
Back to top
View user's profile Send private message Visit poster's website Yahoo Messenger
simon.starkie
PostPosted: Wed Apr 23, 2003 9:16 pm    Post subject: I have the same problem. The same workaround fixed. But why? Reply with quote

Disciple

Joined: 24 Mar 2002
Posts: 180

I had the same problem as jonstrande and the same workaround he used also solved the problem for me (convert CorrelId character string into bytes).

I have heard that there is a known problem with JMS mapping the CorrelId from MQ to JMS. For example, another programmer at our site who also had this problem and got around it by using the MQJI classes to directly reference the CorrelId in the MD rather than using the JMS CorrelId (CID).

Is there a bug in IBM's JMS implementation or are we all making the same mistake

Here is my code (not great code, but hopfully you get the idea)

/**
* @author Ann Starkie
*
* To change this generated comment edit the template variable "typecomment":
* Window>Preferences>Java>Templates.
* To enable and disable the creation of type comments go to
* Window>Preferences>Java>Code Generation.
*/

import javax.jms.*;
import com.ibm.mq.jms.*;
import java.io.*;

public class testJMS
{
private QueueSession qSession;
public static void main(String[] args) {
// Parameters
// 1. Request Queue Name
// 2. Reply Queue Name
// 3. Queue Manager Name
// 4. Input File
String RequestQName = args[0];
String ReplyQName = args[1];
String qManagerName = args[2];
String qFile = args[3];
String theUser = args[4];
String thePassword = args[5];
//Note that any password specified in the createQueueConnection() method
//is not authenticated by the IBM's MQ JMS implementation without you
//implementing your own security exits.
// "Ann Starkie" works, but not "Simon Starkie" (gets MQJMS2013)
//BOTH are in group mqm!!!!!!!!!!!!!!!!!!!!

MQQueueConnectionFactory qConnFactory = new MQQueueConnectionFactory();
try
{
qConnFactory.setQueueManager(qManagerName);
QueueConnection qConn = qConnFactory.createQueueConnection(theUser,thePassword);
QueueSession qSession =
qConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue requestQueue = new MQQueue("queue:///" + RequestQName);
QueueSender requestQueueSender = qSession.createSender(requestQueue);
Queue replyQueue = new MQQueue("queue:///" + ReplyQName);
QueueSender replyQueueSender = qSession.createSender(replyQueue);

//SEND
TextMessage message = qSession.createTextMessage();
// open the file
FileInputStream fis = new FileInputStream(qFile);
// read all its bytes
long filelen = new File(qFile).length();
byte[] vec = new byte[(int)filelen];
fis.read(vec);
int n=1;
StringBuffer vec3 = new StringBuffer();
for(int i = 0; i < filelen ; i++)
{
vec3.append((char)vec[i]);
}
fis.close();
message.setText(vec3.toString());
String RequestMessage = message.getText();
System.out.println( "\n" + "Request Message=\n" + RequestMessage);
String theCorrelId = "simon_says_hello";
message.setJMSCorrelationID(theCorrelId);
requestQueueSender.send(message);
String testString = message.getJMSCorrelationID();
System.out.println("SEND JMSCorrelId=" + testString);

//RECEIVE
// convert CorrelId character string into bytes
byte [] bytes = testString.getBytes();
StringBuffer sb = new StringBuffer();
for(int i = 0; i < bytes.length ; i++)
{
sb.append(Integer.toHexString(bytes[i]));
}
int correlationIDLength = 48;
int zerosToFill = correlationIDLength - sb.length();
for(int i = 0; i < zerosToFill; i++ )
{
sb.append("0");
}

// prepare to receive messages
qConn.start(); // MUST START QueueConnection TO RECEIVE ANY MESSAGES

// THIS WORKS
System.out.println("RECEIVE JMSCorrelId=" + sb.toString());
QueueReceiver qReceiver = qSession.createReceiver(replyQueue,"JMSCorrelationID = 'ID:"+sb.toString()+"'");

// THIS DOES NOT WORK - THE MESSAGE IS NOT FOUND
// System.out.println("RECEIVE JMSCorrelId=" + theCorrelId);
// QueueReceiver qReceiver = qSession.createReceiver(replyQueue,"JMSCorrelationID = 'ID:"+"simon_says_jello"+"'");

// THIS DOES NOT WORK - THE MESSAGE IS NOT FOUND
// System.out.println("RECEIVE JMSCorrelId=" + theCorrelId);
// QueueReceiver qReceiver = qSession.createReceiver(replyQueue,"JMSCorrelationID = 'ID:"+theCorrelId+"'");

// receive the message using CorrelId or timeout after 10 seconds
Message inMessage = qReceiver.receive(10000); // get the message or timeout after 10000 milliseconds

// Check to see if the receive call has actually returned a
// message. If it hasn't, report this and throw an exception...
if( inMessage == null )
{
System.out.println( "The attempt to read the message back again " +
"failed, apparently because it wasn't there");
qReceiver.close();
throw new JMSException("Failed to get message back again");
}

// ...otherwise display the message
System.out.println( "\n" + "Reply Message CorrelId=" + inMessage.getJMSCorrelationID());
if (inMessage != null)
{
if (inMessage instanceof TextMessage)
{
message = (TextMessage) inMessage;
System.out.println("Reading message: " +
message.getText());
}
}
qSession.close();

}
catch (JMSException e)
{
System.out.println("Exception: " + e.toString());
}
catch (FileNotFoundException e)
{
System.out.println("File Not Found Exception: " + e.toString());
}
catch (IOException e)
{
System.out.println("File IOException: " + e.toString());
}
}
}
Back to top
View user's profile Send private message
kingdon
PostPosted: Thu Apr 24, 2003 4:17 am    Post subject: Reply with quote

Acolyte

Joined: 14 Jan 2002
Posts: 63
Location: UK

This seems to crop up at regular intervals, but I have never been able to reproduce any problems with the MQJMS implementation. There are however, plenty of places where you can trip up in the application code. For example:

sb.append(Integer.toHexString(bytes[i]));

won't work in the general case because you need to catch values which return a single digit and prefix a '0'.

// THIS DOES NOT WORK - THE MESSAGE IS NOT FOUND
// System.out.println("RECEIVE JMSCorrelId=" + theCorrelId);
// QueueReceiver qReceiver = qSession.createReceiver(replyQueue,"JMSCorrelationID = 'ID:"+"simon_says_jello"+"'");

won't work because you don't prefix string values of correlationID with ID:, and "jello" is not equal to "hello"

// THIS DOES NOT WORK - THE MESSAGE IS NOT FOUND
// System.out.println("RECEIVE JMSCorrelId=" + theCorrelId);
// QueueReceiver qReceiver = qSession.createReceiver(replyQueue,"JMSCorrelationID = 'ID:"+theCorrelId+"'");

won't work because of the ID:

Other easy to make mistakes include a typo in the name of the identifier (e.g. JMSCorelationID or JMSCorrelationId) and forgetting the quotes around the literal.

Cheers,
James.
Back to top
View user's profile Send private message
simon.starkie
PostPosted: Fri Apr 25, 2003 6:20 am    Post subject: Please post a sample. Reply with quote

Disciple

Joined: 24 Mar 2002
Posts: 180

Thanks James.
Could you please post the code you used to test MQJMS.
Cheers.
Back to top
View user's profile Send private message
kingdon
PostPosted: Wed May 14, 2003 11:50 am    Post subject: Reply with quote

Acolyte

Joined: 14 Jan 2002
Posts: 63
Location: UK

Hi,

Posting the test code used for the product isn't something I'm allowed to do, but I've created a simple example program that demonstrates three of the common use cases for JMSCorrelationID. I believe this has already been sent directly to Simon, but I'll also send it to Brandon for putting on the repository, as it may be helpful for others as well.

Cheers,
James.
Back to top
View user's profile Send private message
simon.starkie
PostPosted: Wed May 14, 2003 1:27 pm    Post subject: Thanks, we got the JMS CorrelId sample. Reply with quote

Disciple

Joined: 24 Mar 2002
Posts: 180

It is a very nice sample including several test cases.

Case B in the sample is consistent with the best practice I have been recommending here. That is, use the unique MessageId from request message that is made available to JMS after the message has been successfully sent to the Messaging Service (in this case MQ).

The MessageId is used as the CorrelId for the subsequent JMS receive.

The triggered application (again, this is a request-reply model to invoke a CICS MQ app) "turns around" the MessageId by moving it to the CorrelId.

The JMS receive is waiting on a CorrelId that is actually the unique MessageId from the send. This particular MessageId value eventually returns to the JMS app receive as the CorrelId because of the "turn around" of the MessageId by the CICS app as previously descried.

In other words, the CICS app does not have to worry about preserving the "user key" in the request message's CorrelId - it simply overlays the CorrelId with the MessageId of the request message. Also, the JMS app does not have to worry about constructing a unique CorrelId - it gets it from the MessageId that was assigned when the message was sent.

Thanks for the excellent help and support from IBM.
Back to top
View user's profile Send private message
mverh
PostPosted: Wed Nov 12, 2003 6:50 am    Post subject: Reply with quote

Voyager

Joined: 06 Mar 2002
Posts: 97

Did the sample code showing the use of msgId and corellId within a JMS req/rep ever get posted? I looked but didn't see it. If you have a copy I'd appreciate it if you emailed it to me at marc_verhiel@candle.com...thx
Back to top
View user's profile Send private message
bower5932
PostPosted: Wed Nov 12, 2003 7:28 am    Post subject: Reply with quote

Jedi Knight

Joined: 27 Aug 2001
Posts: 3023
Location: Dallas, TX, USA

I'll send you a copy off-line.
Back to top
View user's profile Send private message Send e-mail Visit poster's website AIM Address Yahoo Messenger
techno
PostPosted: Wed May 12, 2004 10:23 am    Post subject: Reply with quote

Chevalier

Joined: 22 Jan 2003
Posts: 429

I see correlationid getting converted to hexa and all. Is this valid even for generated MsgId ( copying generated msgid to corrid) also? What is the concept here?

Thanks
Back to top
View user's profile Send private message
jefflowrey
PostPosted: Wed May 12, 2004 11:01 am    Post subject: Reply with quote

Grand Poobah

Joined: 16 Oct 2002
Posts: 19981

techno wrote:
I see correlationid getting converted to hexa and all. Is this valid even for generated MsgId ( copying generated msgid to corrid) also? What is the concept here?

Thanks


The Message ID field and the Correlation ID field in the MQMD are defined as BYTE24 fields. Which means that they consist of 24 *bytes*, not *characters*.

A byte can hold binary values that are not legal as characters. You can't simply treat a byte as a String and expect it to work.
_________________
I am *not* the model of the modern major general.
Back to top
View user's profile Send private message
techno
PostPosted: Wed May 12, 2004 3:49 pm    Post subject: Reply with quote

Chevalier

Joined: 22 Jan 2003
Posts: 429

I have another similar thread going on parallel to this ....


But getJMSCorrelationID() is giving String. How do I use correlationid in selector? As byte24 or String?


Thanks,
Back to top
View user's profile Send private message
jefflowrey
PostPosted: Wed May 12, 2004 4:07 pm    Post subject: Reply with quote

Grand Poobah

Joined: 16 Oct 2002
Posts: 19981

techno wrote:
I have another similar thread going on parallel to this ....

Yes. I know.

Please don't do that.

techno wrote:
But getJMSCorrelationID() is giving String. How do I use correlationid in selector? As byte24 or String?


See my amended/edited response in that other thread.

I got scared and ran away on the remainder of your question in that thread. You seemed to be talking about running Java on z/OS.
_________________
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 » Trouble w\JMSMessageID, JMSCorrelationID & message sele
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.