jsr368-experts@jms-spec.java.net

[jsr368-experts] JMS_SPEC-155 (JMS 2.0 introduced incompatible changes to createSession(bool,int))

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Thu, 04 Dec 2014 12:30:05 +0000

Here's the next proposed correction for the JMS 2.0 errata release.
https://java.net/jira/browse/JMS_SPEC-155
(JMS 2.0 introduced an incompatible restriction on creating two sessions per connection in Java EE)

This is quite a significant correction, so I'll explain the issue in some detail and then give a high-level summary of
how I propose to correct its. You can read a more nicely-formatted version in the JIRA issue.

I'll follow this up with a second email containing a line-by-line list of spec and javadoc changes.

Nigel


The background
--------------

Prior to JMS 2.0, a number of requirements for the behaviour of the JMS API in Java EE applications were defined in the
Java EE 6 platform specification and in the EJB 3.1 specification, but were not mentioned in the JMS specification or
javadocs. This was confusing for users. To remedy this, JMS 2.0 was extended to incorporate these requirements.

Those extensions to JMS 2.0 were intended to be a rearrangement and clarification of existing requirements and were not
intended to introduce changes which were incompatible with Java EE 6 and EJB 3.1 or which would require changes to
existing applications.

However it appears that JMS 2.0 may have introduced a number incompatible changes related to the behaviour of the
ConnectionFactory method createSession(boolean transacted, int acknowledgeMode) in a Java EE web or EJB application in
the case where there is no active JTA transaction in progress and the application has specified the parameter values
(true, SESSION_TRANSACTED) or (false,CLIENT_ACKNOWLEDGE).

In the EJB 3.1 specification, section 13.3.5 states

     "The Bean Provider should not use the JMS acknowledge method either within
     a transaction or within an unspecified transaction context. Message
     acknowledgment in an unspecified transaction context is handled by the
     container."

The term "unspecified transaction context" is explained in EJB 3.1 section 13.6.5. Although it does not say so
explicitly, it is understood to mean those cases where there is there is no active container-managed transaction in
progress or where bean-managed transactions are specified but there is no active UserTransaction in progress.

When this requirement was incorporated into the JMS specification, it became the following text in JMS 2.0 section 12.3:

     "When an application creates a Session or JMSContext in a Java EE web or EJB
     container, and there is no active JTA transaction in progress, then the
     session that is created will be non-transacted and will be automatically-
     acknowledged. The use of local transactions or client acknowledgement is
     still not permitted. Parameters may be specified when creating the Session
     or JMSContext to specify whether the acknowledgement mode should be
     AUTO_ACKNOWLEDGE or DUPS_OK_ACKNOWLEDGE. If any other session parameter
     values are specified they will be ignored and an acknowledgement mode of
     AUTO_ACKNOWLEDGE used."

The problem
-----------

Although the JMS 2.0 specification clearly conveys the intent of the EJB 3.1 specification, the requirement given in the
EJB specification was loosely worded:

* EJB 3.1 uses the phrase "should not use the JMS acknowledge method" rather than "must not use the JMS acknowledge method"

* EJB 3.1 uses the phrase "Message acknowledgment...is handled by the container" without explicitly stating what would
happen if the application tries to use client-acknowledgement or local transactions.

It therefore appears (with hindsight) that JMS 2.0 has introduced some additional requirements which are additional to
EJB 3.1. In particular it has introduced the requirement that if the application specifies the session parameters as
(true, SESSION_TRANSACTED) or (false, CLIENT_ACKNOWLEDGE) then they will be ignored and an acknowledgement mode of
AUTO_ACKNOWLEDGE used.

The "Backwards compatibility requirements for Java EE specifications" can be found at
https://java.net/projects/javaee-spec/pages/CompatibilityRequirements

It could be argued that this change does not violate these compatibility requirements. The compatibility requirements
state that "Where behavior was undefined or optional in the previous version of the specification then it is permissible
to define more explicit behavior in a later version.", which would appear to allow this change (treating EJB 3.1 as the
"previous version").

The compatibility requirements also require that "applications that change to using the new version of the specification
do not see changes to behaviour that were mandated by the previous version of the specification.". Again, it could be
argued that JMS 2.0 did not change behaviour that was mandated by the previous version of the specification" (again
(treating EJB 3.1 as the "previous version").

However it has been discovered that at least one JMS vendor has interpreted the EJB 3.1 specification as allowing both
client-acknowledgement and local transactions to be used in a Java EE web or EJB application in the case where there is
no active JTA transaction.

Given that the EJB 3.1 specification is loosely worded, and that there were no CTS tests to require otherwise, it would
appear that this was valid. Therefore, introducing the requirements added in JMS 2.0 would change the behaviour of
existing applications, which is contrary to the intent of the backwards compatibility requirements for Java EE
specifications.

The proposal
------------

(This is a summary. Details will follow)

To avoid forcing JMS vendors to change the the behaviour of existing applications, it is proposed to revise section 12.3
of the JMS 2.0 specification, and the corresponding javadocs, as follows:

* to recommend (rather than require) that applications do not call createSession with the parameters (true,
SESSION_TRANSACTED) or (false,CLIENT_ACKNOWLEDGE) when in a Java EE EJB or web application and there is no active JTA
transaction, and warn that applications which specify these parameter values may not be portable,

* to allow JMS providers to choose the behaviour they provide if the application specifies the parameters (true,
SESSION_TRANSACTED) when in a Java EE EJB or web application and there is no active JTA transaction from the following
options:

     - the JMS provider is recommended but not required to ignore the specified
     parameters and instead provide a non-transacted, auto-acknowledged session.

     - the JMS provider may alternatively provide a local transacted session.

* to allow JMS providers to choose the behaviour they provide if the application specifies the parameters
(false,CLIENT_ACKNOWLEDGE) when in a Java EE EJB or web application and there is no active JTA transaction from the
following options:

     - the JMS provider is recommended but not required to ignore the specified
     parameters and instead provide a non-transacted, auto-acknowledged session.

     - the JMS provider may alternatively provide a non-transacted session with
     client acknowledgement.

Change related new methods to stay consistent
---------------------------------------------

Although the issue of backwards compatibility applies only to the following existing methods:
12345678901234567890123456789012345678901234567890123456789012345678901234567890
     Connection method createSession(
         boolean transacted, int acknowledgeMode)

     QueueConnection method createQueueSession(
         boolean transacted, int acknowledgeMode)

     TopicConnection method createTopicSession(
         boolean transacted, int acknowledgeMode)

it is proposed that for consistency the same changes are also made to the following methods added in JMS 2.0:

     Connection method createSession(
         int sessionMode)

     ConnectionFactory method createContext(
         int sessionMode).


Nigel