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 » Problem with hashCode() on MQTopic and MQQueue

Post new topic  Reply to topic
 Problem with hashCode() on MQTopic and MQQueue « View previous topic :: View next topic » 
Author Message
Cyrille Le Clerc
PostPosted: Tue Jul 06, 2010 6:45 am    Post subject: Problem with hashCode() on MQTopic and MQQueue Reply with quote

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
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
fjb_saper
PostPosted: Tue Jul 06, 2010 12:23 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
Cyrille Le Clerc
PostPosted: Wed Jul 07, 2010 12:08 am    Post subject: Reply with quote

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.

Code:

_________________
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
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
mqjeff
PostPosted: Wed Jul 07, 2010 1:52 am    Post subject: Reply with quote

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
View user's profile Send private message
Cyrille Le Clerc
PostPosted: Wed Jul 07, 2010 2:05 am    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
calanais
PostPosted: Thu Jul 08, 2010 12:09 am    Post subject: Reply with quote

Apprentice

Joined: 12 Mar 2010
Posts: 32

Check the latest service fixes - specifically http://www-01.ibm.com/support/docview.wss?rs=171&uid=swg1IZ53893 in WMQ 7.0.1.2
Back to top
View user's profile Send private message
Cyrille Le Clerc
PostPosted: Thu Jul 08, 2010 1:42 am    Post subject: Reply with quote

Novice

Joined: 23 May 2007
Posts: 12
Location: France

Thanks so much!

This is the solution to my problem .

Cyrille
_________________
Cyrille Le Clerc
cyrille@cyrilleleclerc.com
cleclerc@xebia.fr
http://blog.xebia.fr
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » IBM MQ Java / JMS » Problem with hashCode() on MQTopic and MQQueue
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.