jsr343-experts@jms-spec.java.net

[jsr343-experts] (JMS_SPEC-48) Specify that connection.stop() or close() may not be called from a MessageListener

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Tue, 16 Aug 2011 15:05:24 +0100

I have created this JIRA issue
http://java.net/jira/browse/JMS_SPEC-48

This issue was raised by Graham. As always, please do give your comments.

Please

Possible deadlock when calling connection.stop()
-----------------------------------------------

If the javax.jms.MessageListener method onMessage calls Connection.stop() then, according to the JMS 1.1 specification,
deadlock may result.

Section 4.3.4 "Pausing Delivery of Incoming Messages" states:

"If MessageListeners are running when stop is invoked, stop must wait until all of them have returned before it may
return. While these MessageListeners are completing, they must have the full services of the connection available to them."

This means that if a MessageListener calls Connection.stop() then the call to stop() will block forever, waiting for the
onMessage() method which is calling it to return.

To avoid the possibility of applications causing deadlock, the JMS specification needs to be clarified to state that a
MessageListener must not call connection.stop().

The section above states that a MessageListener must have "the full services of the connection" available to it. The
meaning of the term "full services" is not defined, but it needs to be made clear that this does not include the ability
to call Connection.stop().

Possible deadlock when calling connection.close()
------------------------------------------------

A similar issue exists for Connection.close(). If the javax.jms.MessageListener method onMessage calls
Connection.close() then, according to the JMS 1.1 specification, deadlock may result.

Section 4.3.5 "Closing a connection" states:

"If one or more of the connection's session's message listeners is processing a message at the point 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.

"When connection close is invoked it should not return until message processing has been shut down in an orderly
fashion. This means that all message listeners that may have been running have returned, and that all pending receives
have returned."

Again, this means that if a MessageListener calls Connection.close() then the call to close() will block forever,
waiting for the onMessage() method which is calling it to return.

To avoid the possibility of applications causing deadlock, the JMS specification needs similarly to be clarified to
state that a MessageListener must not call connection.close().

The section above states that a MessageListener must have "all the facilities of the connection" available to it. The
meaning of the term "all the facilities" is again not defined, but it needs to be made clear that those does not include
the ability to call Connection.close().

Enforcement
-----------

JMS provider should be required to throw a javax.jms.IllegalStateException if Connection.stop() or Connection.close() is
called from the onMessage method of a javax.jms.MessageListener.