Here's the next proposed correction for the JMS 2.0 errata release. This email describes the issue and the proposed
solution. A follow-up email will propose the changes to wording that would be needed.
This is
https://java.net/jira/browse/JMS_SPEC-158
(JMS 2.0 introduced incompatible changes to Connection.stop and close and Session.close)
Any comments or questions?
Background: JMS 1.1
-------------------
The JMS 1.1 specification stated that the stop method on Connection, and the close methods on Connection, Session and
MessageConsumer must not return until any message listeners have returned.
This had the unfortunate consequence of requiring that if these methods were called from a message listener on its own
Connection, Session or MessageConsumer then deadlock would occur and these methods would never return.
This error in JMS 1.1 was well-known to developers of JMS 1.1 implementations. Some vendors decided (many years ago)
that it was unacceptable to cause customer applications to block for ever and so took the decision to ignore the
requirement that these methods block for ever when called from a message listener on its own Connection, Session or
MessageConsumer.
Changes in JMS 2.0
------------------
The JMS 2.0 specification (JMS_SPEC-48) addressed this error by amending the required behaviour to avoid the possibility
of deadlock. It did so in two different ways:
* In the case of the stop method on Connection, and the close methods on Connection and Session, the requirement to
block for ever when these methods were called from a message listener (on its own Connection or Session) was replaced by
the requirement to throw a javax.jms.IllegalStateException.
* However in the case of the close method on MessageConsumer, the requirement to block for ever when this method was
called from a message listener (on its own MessageConsumer) was removed by allowing the close method to return normally.
The problem
-----------
The change introduced in JMS 2.0 replaces the requirement to block for ever with the requirement to throw an exception.
The expert group considered that this was not an incompatible change since the old behaviour was clearly unacceptable
and no application would rely on it.
However this change does force an incompatible change on those JMS vendors which, many years ago, took the unilateral
decision to ignore the erroneous requirement in JMS 1.1. The new requirements of JMS 2.0 means that existing
applications which called stop and close from within a message listener, and which previously worked just fine, will now
encounter an exception and fail.
Although, strictly speaking, JMS vendors that ignored the original JMS 1.1 requirement were violating the specification,
this was not an unreasonable thing to do given that JMS 1.1 was clearly erroneous and that no further versions of JMS
were developed until JMS 2.0 over a decade later.
This means that, even though the change in JMS 2.0 was technically valid, in practice it has introduced an incompatible
change for some JMS vendors which would force them to break existing applications.
The solution
-------------
It is proposed to amend JMS 2.0 to state that the requirement to throw an exception is OPTIONAL. JMS vendors would be
allowed to decide whether these methods should throw an exception or return normally. This would allow vendors which
have long allowed these methods to return normally to continue to do so, and avoid breaking existing applications.
Existing JMS 2.0 implementations would not need to change.
Since this would mean that some vendors would throw an exception and some would not, applications which relied on these
methods being called from a message listener would not be portable, and the specification would need to warn of this.
(In the longer term, this lack of portability could be resolved by removing the option to throw an exception. That is
the subject of a separate issue JMS_SPEC-159 which might be considered for JMS 2.1.)
Nigel