|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
Problem with hashCode() on MQTopic and MQQueue |
« View previous topic :: View next topic » |
Author |
Message
|
Cyrille Le Clerc |
Posted: Tue Jul 06, 2010 6:45 am Post subject: Problem with hashCode() on MQTopic and MQQueue |
|
|
Novice
Joined: 23 May 2007 Posts: 12 Location: France
|
Dear all,
I wanted to share with you a contact admin bug I faced : I got a MessageProducer leak in Spring Framework's CachingConnectionFactory with WMQ 7.0.1 jms connector because the hashCode() methods of identical MQTopics or MQQueues do not return the same value.
The error message is :
Code: |
Caused by: com.ibm.msg.client.jms.DetailedResourceAllocationException: JMSWMQ2006: Failed to open MQ topic 'MY_TOPIC'.
JMS attempted to perform an MQOPEN, but WebSphere MQ reported an error.
Use the linked exception to determine the cause of this error. Check that the specified topic and queue manager are defined correctly.Â
     at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:588)Â
     at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:236)Â
     at com.ibm.msg.client.wmq.internal.WMQMessageProducer.checkJmqiCallSuccess(WMQMessageProducer.java:1046)Â
     at com.ibm.msg.client.wmq.internal.WMQMessageProducer.checkJmqiCallSuccess(WMQMessageProducer.java:1002)Â
     at com.ibm.msg.client.wmq.internal.WMQMessageProducer.access$800(WMQMessageProducer.java:63)Â
     at com.ibm.msg.client.wmq.internal.WMQMessageProducer$SpiIdentifiedProducerShadow.initialise(WMQMessageProducer.java:763)Â
     at com.ibm.msg.client.wmq.internal.WMQMessageProducer.<init>(WMQMessageProducer.java:977)Â
     at com.ibm.msg.client.wmq.internal.WMQSession.createProducer(WMQSession.java:943)Â
     at com.ibm.msg.client.jms.internal.JmsSessionImpl.createProducer(JmsSessionImpl.java:1162)Â
     at com.ibm.mq.jms.MQSession.createProducer(MQSession.java:593)Â
     at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler
.getCachedProducer(CachingConnectionFactory.java:347)Â
     at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler
.invoke(CachingConnectionFactory.java:319)Â
     at $Proxy9.createProducer(Unknown Source)Â
     at org.springframework.jms.core.JmsTemplate.doCreateProducer(JmsTemplate.java:971)Â
     ...
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2017' ('MQRC_HANDLE_NOT_AVAILABLE').Â
     at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:223)Â
     ... |
A simple test case is :
Code: |
MQConnectionFactory connectionFactory = new MQConnectionFactory();
connectionFactory.setHostName("localhost");
connectionFactory.setPort(1414);
connectionFactory.setTransportType(1);
Connection cnn = connectionFactory.createConnection();
Session session = cnn.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue1 = session.createQueue("TEST_QUEUE");
Queue queue2 = session.createQueue("TEST_QUEUE");
Assert.assertEquals(queue1, queue2);
Assert.assertEquals("hashCode()", queue1.hashCode(), queue2.hashCode());
==> throws an"AssertionFailedError: hashCode() expected:<27940859> but was:<7749469>" !!!
|
I found a temporary workaround wrapping the MQ ConnectionFactory, Connection, Session, Topic and Queue with a thin layer that fixes this Topic.hashCode() and Queue.hashCode() issue.
A long term fix would be both MQ jar to fix its behavior (the equal method already works properly) and probably Spring Framework's CachingConnectionFactory to protect itself relying on Topic.getTopicName() / Queue.getQueueName() rather than on the Topic / Queue. It already did it for Messageconsumers for a similar problem with MQ.
Once I fixed this, Spring Framework's CachingConnectionFactory works like a charm to pool sessions, message producers and message consumers .
Hope this will spare time to other people.
Cyrille _________________ Cyrille Le Clerc
cyrille@cyrilleleclerc.com
cleclerc@xebia.fr
http://blog.xebia.fr |
|
Back to top |
|
 |
fjb_saper |
Posted: Tue Jul 06, 2010 12:23 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Cyrille,
I'm not so current on assertions so please bear with me.
AFAIK you would have 2 instances of the same queue however
queue1 == queue2 should report false and queue1.equals(queue2) might report true, only if both destinations have the same value for all of their attributes.
Remember some of the subtleties around String where
String a = "test";
String b = "test";
a == b => false
a.equals(b) => true
Also you are looking at a ConnectionFactory without specification.
At this point you are probably looking at a Destination which is the same for queue and topic and should as such have the same hash code...
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
Cyrille Le Clerc |
Posted: Wed Jul 07, 2010 12:08 am Post subject: |
|
|
Novice
Joined: 23 May 2007 Posts: 12 Location: France
|
Hello FJB,
I was not clear enough, "Assert.assertEquals(expected, actual)" comes from JUnit and thus properly uses the "equals()" method rather than "==" .
As defined in the javadoc of "Object.equals()" and "Object.hashCode()", two objects that are equals should produce the same hashCode (1).
My explanation may have been confusing because I talked of MQTopic and MQQueue in the same sentence.
My problem is that two Queue object that are equals do not produce the same hashCode :
Code: |
// two instances of the same queue
Queue testQueueInstance1 = session.createQueue("TEST_QUEUE");
Queue testQueueInstance2 = session.createQueue("TEST_QUEUE");
testQueueInstance1.equals(testQueueInstance2) ===> returns 'true' as expected
testQueueInstance1.hachCode() == testQueueInstance2.hachCode() ==> returns 'false' when 'true' is expected :-(
|
The problem is the same with topics.
As a comparison, ActiveMQ's queues and topics implement both equals() and hashCode(). I feel there is a little bug in WMQ 7 implementation. However, the JMS 1.1 specification does not specify the equality of identical queues and identical topics.
Cyrille
(1) http://java.sun.com/javase/6/docs/api/java/lang/Object.html#hashCode()
Quote: |
If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. |
_________________ Cyrille Le Clerc
cyrille@cyrilleleclerc.com
cleclerc@xebia.fr
http://blog.xebia.fr
Last edited by Cyrille Le Clerc on Sat Jul 24, 2010 4:24 am; edited 1 time in total |
|
Back to top |
|
 |
mqjeff |
Posted: Wed Jul 07, 2010 1:52 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
If you think you have a bug in the MQ code, you need to open a PMR.
I wouldn't expect two MQQueues that were created from the same mq queue to actually be the same object, and thus return the same hashCode nor in fact be equals... I mean, even if they were created from the same session and etc. etc. etc. |
|
Back to top |
|
 |
Cyrille Le Clerc |
Posted: Wed Jul 07, 2010 2:05 am Post subject: |
|
|
Novice
Joined: 23 May 2007 Posts: 12 Location: France
|
Hello Jeff,
I share your expectation to not have the same object instance returned by session.crerateQueue(name) and thus I don't expect to have session.createQueue("test_queue") == session.createQueue("test_queue")
but I would like to have equality that is to say
session.createQueue("test_queue").equals(session.createQueue("test_queue")) and by transitivity session.createQueue("test_queue").hashCode() == session.createQueue("test_queue").hashCode() .
WMQ does half of it offering session.createQueue("test_queue").equals(session.createQueue("test_queue")) and by transitivity should also offer session.createQueue("test_queue").hashCode() == session.createQueue("test_queue").hashCode() .
I initiated the process to open a PMR and in parallel, I proposed to the SpringFramework project to code a workaround for their CachingConnectionFactory.
Cyrille _________________ Cyrille Le Clerc
cyrille@cyrilleleclerc.com
cleclerc@xebia.fr
http://blog.xebia.fr |
|
Back to top |
|
 |
calanais |
Posted: Thu Jul 08, 2010 12:09 am Post subject: |
|
|
Apprentice
Joined: 12 Mar 2010 Posts: 32
|
|
Back to top |
|
 |
Cyrille Le Clerc |
Posted: Thu Jul 08, 2010 1:42 am Post subject: |
|
|
Novice
Joined: 23 May 2007 Posts: 12 Location: France
|
|
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
|
|
|
|