I believe I have found the cause of this problem.

I believe this is a bug in the IBM WS MQ V6.0 JMS provider code.


There is enough evidence in the CTRL-BREAK dump of the previous email
to show the what has gone wrong.

Here is what happened:

0. My primary thread sends lots of messages to a Queue and then waits
until notified by the recever that all messages have arrived, whereupon
is closes the connections.

1. When arrival of all messages is determined my onMessage tells
primary thread (from 0) to issue the Connection.close for the consumers

2. The thread doing the Connection.close does:

JMS API connection.close which
calls SYNCHRONIZED MQSession.close which
calls SessionAsynHelper which blocks waiting until everything is

3. But meanwhile....

my onMessage method returned to the WS MQ internal
MQMessageConsumer.receiveAsync method which calls the SYNCHRONIZED

*** DEADLOCK occurs on the MQSession monitor ***


Basically, by unlucky timing the MQSession.close request occurred
before the MQMessageConsumer.receiveAsync was able to fully complete.


I can workaround this bug simply by introducing a small delay before my
cleanup Connection.close(). This delay allows the
MQMessageConsumer.receiveAsync enough time to complete the message
processing. This probably isn't a general workaround but it is OK for
my case because I happen to know that there will be no more messages
arriving on the Queue I am receiving from....


But really I think the IBM MQ V6.0 JMS provider is in violation of the
JMS specification.

For example



The close method is the only session method that can be called while
some other session method is being executed in another thread.

Yet if I'd done something using the Session API insice my onMessage I
reckon it could've become equally stuck on the MQSession monitor.



If one or more of the connection's sessions' message listeners is
processing a message at the time when connection close is invoked, all
the facilities of the connection and its sessions must remain available
to those listeners until they return control to the JMS provider.

But it didn't seem to behave nicely like that at all....

Any comments?