Issue Details (XML | Word | Printable)

Key: JMS_SPEC-27
Type: Improvement Improvement
Status: Resolved Resolved
Resolution: Fixed
Priority: Critical Critical
Assignee: Nigel Deakin
Reporter: Nigel Deakin
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
jms-spec

Clarify the relationship between the JMS and other Java EE specifications

Created: 06/Jul/11 02:43 PM   Updated: 20/Mar/13 12:59 PM   Resolved: 20/Mar/13 12:59 PM
Component/s: None
Affects Version/s: 1.1
Fix Version/s: 2.0ED, 2.0

Time Tracking:
Not Specified

Tags: ed20-added
Participants: Nigel Deakin


 Description  « Hide

Summary

We need to clarify the relationship between the JMS and other Java EE specifications. This is mainly a documentation exercise, especially for those methods which are forbidden or modified in a EJB or Web container, but there are some ambiguities, especially when the transaction context is undefined.

More detail

If you want use the JMS API in a Java EE application such as a EJB or servlet you soon discover that much of the JMS spec (including the JMS javadocs) does not apply, at least in the EJB and web containers. For example, you aren't allowed to create message listeners, you need to defined MDBs instead. You aren't allowed to create local transactions, you need to use CMT or BMT transactions instead. You aren't allowed to set clientID on a connection. You aren't allowed to perform client acknowledgement. Essentially, in a Java EE container, the JMS API is simply different. However this is not explained in the JMS spec but is described in other specs, notably the EJB and Java EE platform specs.

Some of this information of necessity in other specs, but the absence of any mention of it in the JMS spec or javadocs is confusing to users.

I would like the JMS expert group to review what it says about JMS in other specs and consider whether this material should be moved to the JMS spec, duplicated in the JMS spec, or cross-referenced from the JMS spec. In addition the javadocs need to be clarified to mention that some API is not allowed, or has a different effect, in a Java EE web or EJB container.

I see this mainly as a documentation exercise. However this analysis will inevitably identify that some areas of behaviour are not well defined. For example, the EJB spec states explicitly that in an "undefined transactional context" it is not defined how the JMS provider should handle transactions. This means that vendors may behave differently which reduces the portability of application. If possible this should be resolved.



Nigel Deakin made changes - 06/Jul/11 02:43 PM
Field Original Value New Value
Assignee Nigel Deakin [ nigeldeakin ]
Nigel Deakin added a comment - 26/Jan/12 06:25 PM - edited

I've now updated the API, javadocs and the draft spec.
The updated draft spec is here:
http://java.net/projects/jms-spec/sources/repository/content/jms2.0/specification/word/JMS20.pdf

I've written a completely new section to add to the new chapter 12 "Use of JMS API in Java EE applications" which was added for JMS_SPEC-45. This is intended to simply restate what is already defined in the EJB 3.1 and Java EE 6 platform specs, though I have extended it to cover the simplified API. here it is:

12.2. Restrictions on the use of JMS API in the Java EE web or EJB container

JMS applications which run in the Java EE web or EJB container are subject to a number of restrictions in the way the JMS API may be used. These restrictions are necessary for the following reasons:

  • In a Java EE web or EJB container, a JMS provider operates as a transactional resource manager which must participate in JTA transactions as defined in the Java EE platform specification. This overrides the behaviour of JMS sessions as defined elsewhere in the JMS specification. For more details see section 12.3 "Behaviour of JMS sessions in the Java EE web or EJB container".
  • The Java EE web or EJB containers need to be able to manage the threads used to run applications.
  • The Java EE web and EJB containers perform connection management which may include the pooling of JMS connections.

The restrictions described in this section do not apply to the Java EE application client container.
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 MessagingContext object's createMessagingContext method then a JMS{{RuntimeException}} should be thrown, since the first messaging context already contains a connection and session and this method would create a second session on the same connection.

The following methods are intended for use by the application server and their use by applications running in the Java EE web or EJB container may interfere with the container's ability to properly manage the threads used in the runtime environment. They must therefore not be called by applications running in the Java EE web or EJB container:

  • javax.jms.Session method setMessageListener
  • javax.jms.Session method getMessageListener
  • javax.jms.Session method setBatchMessageListener
  • javax.jms.Session method getBatchMessageListener
  • javax.jms.Session method run
  • javax.jms.Connection method createConnectionConsumer
  • javax.jms.Connection method createDurableConnectionConsumer

The following methods may interfere with the container's ability to properly manage the threads used in the runtime environment and must not be used by applications running in the Java EE web or EJB container:

  • javax.jms.MessageConsumer method setMessageListener
  • javax.jms.MessageConsumer method getMessageListener
  • javax.jms.MessageConsumer method setBatchMessageListener
  • javax.jms.MessageConsumer method getBatchMessageListener
  • javax.jms.MessagingContext method setMessageListener
  • javax.jms.MessagingContext method getMessageListener
  • javax.jms.MessagingContext method setBatchMessageListener
  • javax.jms.MessagingContext method getBatchMessageListener

This restriction means that applications running in the Java EE web or EJB container which need to receive messages asynchronously may only do so using message-driven beans.

The following methods may interfere with the container's management of connections and must not be used by applications running in the Java EE web or EJB container:

  • javax.jms.Connection method setClientID
  • javax.jms.Connection method stop
  • javax.jms.Connection method setExceptionListener
  • javax.jms.MessagingContext method setClientID
  • javax.jms.MessagingContext method stop
  • javax.jms.MessagingContext method setExceptionListener

Applications which need to use a specific client identifier must set it on the connection factory, as described in section 4.3.2 "Client Identifier"

All the methods listed in this section may throw a javax.jms.JMSException (if allowed by the method) or a javax.jms.JMSRuntimeException (if not) when called by an application running in the Java EE web or EJB container. This is recommended but not required.


Nigel Deakin added a comment - 26/Jan/12 06:37 PM

The updated Javadocs are here:
http://java.net/projects/jms-spec/sources/repository/content/jms2.0/target/jms-2.0-javadoc.jar

The javadocs for all the methods listed above which are not permitted in a Java EE web or Java EE container now include the following statement:

* This method must not be used in a Java EE web or EJB application. 
* Doing so may cause a <code>JMSException</code> to be thrown though this is not guaranteed.

In addition, the list of exceptions for these methods now states that they may throw a JMSException (or JMSRuntimeException if called in a Java EE web or EJB container, together with the caveat that "it is not guaranteed that an exception is thrown in this case"

The three Connection methods createSession now include the statement:

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

The list of exceptions for these methods states that they will (must) throw a JMSException if "this method is being called in a Java EE web or EJB application and an active session already exists for this connection."

The MessageConsumer method createMessagingContext now includes the statement:

* This method is for use in a Java SE environment or in the Java EE application client container only. 
* It may not be used in a Java EE environment because this would violate
* the Java EE restriction that a connection may have only one session.

The list of exceptions for this method now states that it will (must) throw an exception if "this method is being called in a Java EE web or EJB application"


Nigel Deakin made changes - 03/Feb/12 06:47 PM
Tags eg ed-added eg
Nigel Deakin made changes - 04/Feb/12 06:22 PM
Tags ed-added eg eg
Nigel Deakin made changes - 04/Feb/12 06:22 PM
Tags eg ed20-added eg
Nigel Deakin made changes - 21/Sep/12 01:51 PM
Affects Version/s 2.0ED [ 16048 ]
Affects Version/s 1.1 [ 14685 ]
Nigel Deakin made changes - 21/Sep/12 01:51 PM
Fix Version/s 2.0ED [ 16048 ]
Affects Version/s 1.1 [ 14685 ]
Affects Version/s 2.0ED [ 16048 ]
Tags ed20-added eg ed20-added
Nigel Deakin made changes - 21/Sep/12 02:09 PM
Fix Version/s 2.0 [ 14692 ]
Nigel Deakin added a comment - 20/Mar/13 12:59 PM

This issue is resolved in the JMS 2.0 final release. Marking issue as resolved with a "fix version" of 2.0


Nigel Deakin made changes - 20/Mar/13 12:59 PM
Status Open [ 1 ] Resolved [ 5 ]
Resolution Fixed [ 1 ]