users@jms-spec.java.net

[jms-spec users] [jsr368-experts] JMS 2.0 Errata: JMS_SPEC-157 (JMS 2.0 introduced an incompatible restriction on creating two sessions per connection in Java EE)

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Tue, 02 Dec 2014 12:34:23 +0000

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

I'll explain the issue, and the proposed corrections, in some detail. You can read a more nicely-formatted version in
the JIRA issue.

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, 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 or which would require changes to existing
applications.

However it appears that JMS 2.0 has inadvertently introduced an incompatible change related to the use of the Connection
method createSession in a Java EE web or EJB application when a session already exists for that connection.

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

In the Java EE 6 specification, section EE 6.7 "Java Message Service (JMS) 1.1 Requirements" states that

     "Application components in the web and EJB containers must not attempt to
     create more than one active (not closed) Session object per connection.
     An attempt to use the Connection object’s createSession method when an active
     Session object exists for that connection should be prohibited by the container.
     The container may throw a JMSException if the application component violates
     this restriction. Application client containers must support the creation of
     multiple sessions for each connection."

This wording states that applications "must" not attempt to create more than one session per connection in the Java EE
web or EJB containers. However it only says that the container "should" prohibit this, and that it "may" throw an
exception. In accordance with the generally-accepted interpretations of the words "should" and "may", this means that it
is optional whether or not the createSession method throws an exception.

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

     "Applications running in the Java EE web and EJB containers must not attempt
     to create more than one active (not closed) Session object per connection.

     "If an application attempts to use the Connection object’s createSession method
     when an active Session object exists for that connection then a JMSException
     should be thrown.

     "If an application attempts to use the JMSContext object’s createContext method
     then a JMSRuntimeException should be thrown, since the first JMSContext already
     contains a connection and session and this method would create a second session
     on the same connection."

This wording continues to use the word "should" which keeps it optional whether or not the createSession method (or
createContext method) throws an exception.

In addition to this change, the javadoc for these methods was also updated. Unfortunately the wording used was
inconsistent with that in section 12.2.

The javadoc for createSession states that:

     "Applications running in the Java EE web and EJB containers must not attempt to
     create more than one active (not closed) Session object per connection. If this
     method is called in a Java EE web or EJB container when an active Session object
     already exists for this connection then a JMSException will be thrown."

The words "will be thrown" make it obligatory for the createSession method to throw an exception. This introduces an
additional restriction which was not in Java EE 6 (and is not in JMS 2.0 section 12.2) and inadvertently introduces an
incompatible change which may cause existing applications to fail.

The corresponding javadoc for createContext contains a similar wording:

    "This method must not be used by applications running in the Java EE web or EJB
    containers because doing so would violate the restriction that such an application
    must not attempt to create more than one active (not closed) Session object per
    connection. If this method is called in a Java EE web or EJB container then a
    JMSRuntimeException will be thrown."

This method is new in JMS 2.0 so there is no compatibility issue. Nevertheless the words "will be thrown" make it
obligatory for the createContext method to throw an exception, which is inconsistent with the wording in JMS 2.0 section
12.2 which implies that throwing an exception is optional.

Proposed solution
-----------------

JMS specification section 12.2 "Restrictions on the use of JMS API in the Java EE web or EJB container": No changes are
proposed.

JMS specification section 2.8.2. "Key features of the simplified API": Existing text

    Applications running in the Java EE web and EJB containers are not permitted
    to create more than one active session on a connection...

Modified text: (changed words *thus*)

    Applications running in the Java EE web and EJB containers *must not*
    create more than one active session on a connection...

It is proposed that the javadoc for the Connection object’s three createSession methods be changed to make it consistent
with the Java EE 6 specification and with JMS 2.0 section 12.2.

Javadoc for Connection.html#createSession(): Existing text

    Applications running in the Java EE web and EJB containers must not attempt to
    create more than one active (not closed) Session object per connection. If this
    method is called in a Java EE web or EJB container when an active Session object
    already exists for this connection then a JMSException will be thrown.

Replacement text: (changed word *thus*)

    Applications running in the Java EE web and EJB containers must not attempt to
    create more than one active (not closed) Session object per connection. If this
    method is called in a Java EE web or EJB container when an active Session object
    already exists for this connection then a JMSException *may* be thrown.

Javadoc for Connection.html#createSession(int): Existing text

    Applications running in the Java EE web and EJB containers must not attempt to
    create more than one active (not closed) Session object per connection. If this
    method is called in a Java EE web or EJB container when an active Session object
    already exists for this connection then a JMSException will be thrown.

Replacement text: (changed word *thus*)

    Applications running in the Java EE web and EJB containers must not attempt to
    create more than one active (not closed) Session object per connection. If this
    method is called in a Java EE web or EJB container when an active Session object
    already exists for this connection then a JMSException *may* be thrown.

Javadoc for Connection.html#createSession(boolean, int): Existing text

    Applications running in the Java EE web and EJB containers must not attempt to
    create more than one active (not closed) Session object per connection. If this
    method is called in a Java EE web or EJB container when an active Session object
    already exists for this connection then a JMSException will be thrown.

Replacement text: (changed word *thus*)

    Applications running in the Java EE web and EJB containers must not attempt to
    create more than one active (not closed) Session object per connection. If this
    method is called in a Java EE web or EJB container when an active Session object
    already exists for this connection then a JMSException *may* be thrown.

It is also proposed to make the same change to the JMSContext object’s createContext method to to make it consistent
with JMS 2.0 section 12.2.

Javadoc for JMSContext.html: Existing text

    Applications running in the Java EE web and EJB containers are not permitted to
    create more than one active session on a connection so combining them in a single
    object takes advantage of this restriction to offer a simpler API.

    However applications running in a Java SE environment or in the Java EE application
    client container are permitted to create multiple active sessions on the same connection.

Replacement text: (changed words *thus*)

    Applications running in the Java EE web and EJB containers *must not*
    create more than one active session on a connection so combining them in a single
    object takes advantage of this restriction to offer a simpler API.

    However applications running in a Java SE environment or in the Java EE application
    client container *may* create multiple active sessions on the same connection.

Javadoc for JMSContext.html#createContext(int): Existing text

   This method must not be used by applications running in the Java EE web or EJB containers
   because doing so would violate the restriction that such an application must not attempt
   to create more than one active (not closed) Session object per connection. If this method
   is called in a Java EE web or EJB container then a JMSRuntimeException will be thrown.

Replacement text: (changed word *thus*)

   This method must not be used by applications running in the Java EE web or EJB containers
   because doing so would violate the restriction that such an application must not attempt
   to create more than one active (not closed) Session object per connection. If this method
   is called in a Java EE web or EJB container then a JMSRuntimeException *may* be thrown.