|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
WebsphereMQ JMS MessageSelector not working |
« View previous topic :: View next topic » |
Author |
Message
|
blubbla |
Posted: Thu Jul 12, 2012 7:14 am Post subject: WebsphereMQ JMS MessageSelector not working |
|
|
Newbie
Joined: 12 Jul 2012 Posts: 6
|
Hello,
I just spent a few hours to solve this problem - but I dont get it.
So my scenario is like that:
I have several clients that communicate with a JavaEE server over websphere mq and with a request/reply behaviour. That means, the clients send a request to the request queue - a mdb is listening on it, receiver the messages, does some stuff and sends back to a reply queue, where the calling client waits for the message.
By now the request queue is static, and I want to have a temporary queue as reply queue for each client.
So on client startup, a connection, session, producer and a temporary queue is created ans used by the client for the calls.
That is working quite fine for now.
But I wanted to add a message selector on the reply queue, so I can be sure that the received message is exactly the response to the original request message.
The strange thing: This works only for the first call! (the scenario is NOT multithreaded so far). At the 2nd call, I get an MQRC_OBJECT_IN_USE error.
So, here is my code:
Message replyM = session.createConsumer(tempD, replyId).receive(1000); <-- this is only working on the first call!!!!
Message replyM = session.createConsumer(tempD).receive(1000); <-- this is working all the time
Again - with the message selector, only the first xmlCall() works - for the 2nd I got 2 MQCC_FAILED and reason 2042 MQRC_OBJECT_IN_USE.
Without the message selector, all is working quite fine.
I need some help, thanks :) |
|
Back to top |
|
 |
blubbla |
Posted: Thu Jul 12, 2012 7:16 am Post subject: |
|
|
Newbie
Joined: 12 Jul 2012 Posts: 6
|
Sorry, forgot the complete code, here we go:
Code: |
/* import and package... */
public class Start {
public static void main( String[] args ) throws Exception
{
Start s = new Start();
try {
s.xmlCall();
s.xmlCall();
s.xmlCall();
s.xmlCall();
} catch (Exception e) {
e.printStackTrace();
} finally {
s.close();
}
}
private Connection connection;
private Session session;
private Destination destination;
private MessageProducer producer;
private TemporaryQueue tempD;
public void close()
{
try {
this.connection.close();
System.out.println( "closed" );
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void xmlCall() throws Exception
{
this.connection.start();
TextMessage m = session.createTextMessage( createLoginReq() );
m.setJMSReplyTo( tempD );
producer.send(m);
System.out.println( "message sent with id <" + m.getJMSMessageID() + ">, now wait for reply...");
System.out.println( "wait for 1 seconds til receiving the reply" );
Thread.sleep( 1000 );
String replyId = "JMSCorrelationID='" + m.getJMSMessageID() + "'";
//_____________________________________________________________________
//
Message replyM = session.createConsumer(tempD, replyId).receive(1000);
// Message replyM = session.createConsumer(tempD).receive(1000);
//_____________________________________________________________________
if( replyM == null )
{
System.out.println( "error: no message received...");
}
else
{
System.out.println( "ok: message received");
System.out.println( replyM.toString() );
}
replyM.acknowledge();
this.connection.stop();
}
private String createLoginReq()
{
return "some input for server";
}
public Start() throws JMSException
{
this.connection = getJMSConnection();
// initialize the connection
this.session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
this.tempD = session.createTemporaryQueue();
this.destination = session.createQueue( "destination");
this.producer = session.createProducer(destination);
}
private Connection getJMSConnection()
{
// Variables
Connection connection = null;
// Create JMS objects
try {
// Create a connection factory
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
// Set the properties
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, host);
cf.setIntProperty(WMQConstants.WMQ_PORT, port);
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channel);
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManager);
connection = cf.createConnection();
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return connection;
}
} |
|
|
Back to top |
|
 |
mqjeff |
Posted: Thu Jul 12, 2012 7:29 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
You should create the consumer once, and save it.
Then you should use it to receive messages.
Why do you want one consumer for each and every message on your queue? |
|
Back to top |
|
 |
blubbla |
Posted: Thu Jul 12, 2012 7:35 am Post subject: |
|
|
Newbie
Joined: 12 Jul 2012 Posts: 6
|
But how can this be done?
I usually create the consumer by calling the session.createConsumer(destination) OR session.createConsumer(destination, correlationId)
And of course the correlation ID changes with every call....
is there another way to construct the consumer? |
|
Back to top |
|
 |
blubbla |
Posted: Thu Jul 12, 2012 7:45 am Post subject: |
|
|
Newbie
Joined: 12 Jul 2012 Posts: 6
|
guess there is no way to re-use a message consumer in a reuqest-reply scenario with correlation id, for example the websphere mq tutorial says:
Quote: |
The JMS specification does not allow an application to change the message selector of a message consumer. After an application creates a message consumer with a message selector, the message selector remains for the life of that consumer. If an application requires more than one message selector, the application must create a message consumer for each message selector. |
but anyway,this should be not connected with the error message I got, because from consumer-side there should be no difference if I use a message selector or not... |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Jul 12, 2012 8:39 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
apparently too late in the night... :sorry: _________________ MQ & Broker admin |
|
Back to top |
|
 |
blubbla |
Posted: Mon Jul 16, 2012 2:51 am Post subject: |
|
|
Newbie
Joined: 12 Jul 2012 Posts: 6
|
Hmm, is there any one that knows a working example with that combination (request/reply, temp. queue, selective consumer)? |
|
Back to top |
|
 |
fjb_saper |
Posted: Mon Jul 16, 2012 6:44 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
blubbla wrote: |
Hmm, is there any one that knows a working example with that combination (request/reply, temp. queue, selective consumer)? |
Why would you use a selective consumer when using a dynamic temporary queue? As it is created by the requestor and it's lifetime is limited to the session, you should not have to share it...
Can you be more specific and describe your need / problem in more details?  _________________ MQ & Broker admin |
|
Back to top |
|
 |
blubbla |
Posted: Tue Jul 17, 2012 2:32 am Post subject: |
|
|
Newbie
Joined: 12 Jul 2012 Posts: 6
|
Well, I have a JavaEE server with the busines logic in it (EJB) and a MDB listening on the input ( request ) queue.
There is a standalone GUI that is started multiple times. In this GUI, the user cann calculate some stuff etc....
Each GUI should now create its own temporary reply queue (I guess thats a common and used pattern?). So as long as the program is started, the JMS connection holds the temp. reply queue, and if the GUI is destroyed, the temp. queue is destroyed too.
But there might be some parallel calls on the GUI side. The user could trigger a calculationA, that is sent to the request queue and processed by the server. Meanwhile, on the GUI side, the user could trigger calculationB, which is also sent to request queue.
Now there will be 2 reply messages in the temp. reply queue. And to assign the reply to the correct request, a correlation id would be nice.
An other option woould be to create a temp. queue for every request call, but that is (imo) a bad anti-pattern.
I just don't understand why this is working with static queues and not with temp queue. There is no information about this behavior, and I dont understand the difference, because from my point of view both static and temp. queues are just "normal" destinations. |
|
Back to top |
|
 |
fjb_saper |
Posted: Tue Jul 17, 2012 11:35 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Should work the same as with non dynamic queues. Just remember that a persistent message cannot be delivered to a dynamic temporary queue. If you are dealing with persistent messages, allocating a "normal" queue is better.
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
|
|
 |
|
Page 1 of 1 |
|
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
|
|
|
|