Giter Club home page Giter Club logo

messaging's Introduction

Jakarta Messaging

This repository contain the API definition source code for the Jakarta Messaging API. This is used to generate the official Javadocs.

Web-site details are TBD

Repository structure

This project uses maven as build tool, sources follows maven project structure.

Build from Source

Prerequisites:

  • JDK11+
  • Maven 3.5.4+

Navigate to the directory and Type mvn clean package to produce java api jar file. mvn javadoc:jar will produce javadoc jar file.

Release information

Please take a look here.

messaging's People

Contributors

anadrowski avatar arjantijms avatar cousjava avatar dblevins avatar eclipsewebmaster avatar hussainnm avatar ivargrimstad avatar jasonwee avatar keilw avatar m0mus avatar nderwin avatar ondromih avatar pzygielo avatar rmonson avatar scottmarlow avatar srbala avatar starksm64 avatar tivrfoa avatar yaminikb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

messaging's Issues

Depth of messages for a durable subscription

As a client I would like to get the current approximate number of pending messages for a durable subscription. All existing providers give this information via a custom API or JMX at present.

Affected Versions

[1.1]

Define standard API to create and configure a ConnectionFactory

This is a proposal to extend the JMS specification to define a standard way of instantiating and configuring connection factory objects.

Background

A connection factory is an example of an administered object. The JMS 1.1 specification establishes the convention whereby administered objects (connection factories and destinations) are not created in application code. Instead they are created by an administrator using tools specific to the JMS provider and stored in JNDI. The application code then looks up the connection factory or destination from JNDI and uses them in accordance with the JMS API.

The purpose of this is clearly stated in the specification: it is to allow everything that is non-standard and specific to a particular JMS provider to be kept out of the code itself. (See Relevant sections of the JMS 1.1 Specification below).

In the case of connection factories, this means that the application doesn't have to contain any information about how to connect to the JMS provider. For example, if the JMS provider is running on some remote server, the application doesn't contain any information about the location of the server or the protocol used to connect to it. All this information is defined when the connection factory is created by an administrator, separate from the application itself.

However the JMS specification says nothing about how the connection factory itself is created or configured, other than saying that it is done by "provider-specific facilities". All it says is that:

  • it must implement javax.jms.ConnectionFactory,
  • it must implement javax.naming.Referenceable and java.io.Serializable, so it can be stored in all JNDI naming contexts (section 4.2)
  • it is recommended that implementations "follow the JavaBeans design patterns"
  • it allows client identifier to be set (section 4.3.2)

However the specification does not define:

  • how a connection factory is instantiated
  • how the location of the server is defined
  • how client identifier is set
  • how other properties are set

Now although this omission from the JMS 1.1 specification is no doubt deliberate, it does cause some difficulties:

  • it is not possible to develop standard tools for creating connection factories (and binding them in JNDI) which work with multiple JMS providers

  • in a Java EE environment, there is no standard way of configuring the JMS requirements of a particular application

  • it is inconsistent with way in which a JDBC DataSource objects is defined, both in a Java SE and a Java EE environment. This is discussed more in How JDBC DataSource objects are configured.

Proposals

It is proposed that the way that a ConnectionFactory is created and configured be partially standardised in a manner similar to JDBC DataSource objects, as follows:

  • A ConnectionFactory implementation is a JavaBean, and may be instantiated by executing the no-arg constructor of its implementation class. For example:
ConnectionFactory cf = Class.forName("com.sun.messaging.ConnectionFactory")
  • The JMS specification will define a set of properties which may be used to identify and describe a ConnectionFactory implementation.

| Property name | Type | Description |
| description | String | description of this connection factory |
| user | String | user name (may be overridden when createConnection is called) |
| password | String | password corresponding to user name may be overridden when createConnection is called) |
| networkProtocol | String | network protocol used to communicate with the JMS provider |
| serverName | String | server name of the JMS provider |
| portNumber | String | port number of the JMS provider |
| networkProtocols | String[] | array of network protocols used to communicate with the JMS provider |
| serverNames | String[] | array of server names of the JMS provider |
| portNumbers | String[] | array of port numbers of the JMS provider |
| url | String | Opaque string which defines how to connect to the JMS provider |
| clientId | String | JMS client identifier |

  • ConnectionFactory properties follow the convention specified for properties of JavaBeans components in the JavaBeans 1.01 Specification. ConnectionFactory implementations may augment this set with implementation-specific properties. If new properties are added, they must be given names that do not conflict with the
    standard property names.

  • ConnectionFactory implementations must provide "getter" and "setter" methods for each property they support. These properties typically are intended to be initialized before the object is bound in JNDI for subsequent use by an application.

  • ConnectionFactory properties are not intended to be directly accessible by JMS clients. This design is reinforced by defining the access methods on the implementation class rather than on the public DataSource interface used by applications. Furthermore, the object that the client manipulates can be a wrapper that only
    implements the ConnectionFactory interface. The setter and getter methods for the properties need not be exposed to the client.

  • Management tools that need to manipulate the properties of a ConnectionFactory implementation can access those properties using introspection.

Note that this gives three alternative ways to define how the connection factory should communicate with the server:

  • an opaque URL string

  • a tuple of (networkProtocol, serverName, portNumber), where networkProtocol may be omitted

  • an array of such tuples, represented here as three separate arrays

A JMS provider may support all, some or none of these alternatives.

  • If both URL and one of the other forms are supported and both are supplied, the URL is used.

  • If the single tuple (networkProtocol, serverName, portNumber) is supported, then a single-element array of tuples will also be supported

(Much of the wording above is based on section 9.4.1 DataSource properties of the JDBC 4.0 specification.)

Please also see the following additional information which has been added as separate notes below:

  • How JDBC DataSource objects are configured

  • Relevant sections of the JMS 1.1 Specification

Affected Versions

[1.1]

Define mandatory activation config properties clientId and subscriptionName

This is a request for the JMS and/or EJB specifications to define additional mandatory activation config properties for JMS MDBs. Although MDBs are specified in the EJB specification, this request should be considered first by the JMS 2.0 expert group who may then want to raise it with the EJB 3.2 expert group.

The EJB 3.1 spec is distinctly vague about how a MDB is defined. The relevant sections are 5.4.15, 5.4.16 and 5.4.17.1. The only activation config properties defined are acknowledgeMode (only used when transactions are bean-managed, and which must be either Auto-acknowledge or Dups-ok-acknowledge), messageSelector, destinationType (which must be must be either javax.jms.Queue or javax.jms.Topic) and subscriptionDurability (which must be either Durable or NonDurable). But it doesn't specify how the destination is defined or, when subscriptionDurability is Durable, how the subscription name and client identifier are defined.

The JCA 1.6 spec has some additional guidance, at least for MDBs that use a resource adapter. Section B2 states that providers are "strongly encouraged" to provide the properties mentioned above and also destination, subscriptionName and clientId, with destination and destinationType as "required" properties.

Whatever else we do, there seems to be a clear need to make these mandatory for JMS MDBs, whether or not they use JCA.

The JMS 2.0 and EJB 3.2 expert groups should also decide whether the EJB spec is the best place to list such JMS-specific details. Although MDBs (which are not just for JMS) should remain in the EJB spec, perhaps any additional specification for JMS MDBs should be in the JMS spec.

Clarify and improve Connection.createSession

In the JMS 1.1 specification, the following method on a javax.jms.Connection is used to create a javax.jms.Session:

Session createSession(boolean transacted, int acknowledgeMode) throws JMSException

where transacted may be set to true or false and
acknowledgeMode may be set to Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE, and Session.DUPS_OK_ACKNOWLEDGE

(There are similar methods on javax.jms.QueueConnection and javax.jms.TopicConnection: this whole issue applies to all three.)

This is a rather confusing method for several reasons:

  • It uses two arguments to define a single aspect of the session
  • In a Java EE transaction, both arguments are ignored anyway
  • In a Java EE unspecified transaction context, the meaning of the arguments is undefined and unclear

It uses two arguments to define the same thing

This method uses two arguments to define what is in practice a single aspect of the session with four possibilities: if transacted is set to false then the session is non-transacted and the acknowledgeMode argument defines which of three kinds of acknowledgement are used when receiving messages. If transacted is set to true then the acknowledgeMode argument is ignored.

This is inconsistent with the method Session.getAcknowledgeMode() which returns one of four values: Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE, or Session.DUPS_OK_ACKNOWLEDGE if the session is not transacted and Session.SESSION_TRANSACTED if the session is transacted.

This also leads to code which is potentially misleading, since if transacted is false the user still has to set acknowledgeMode to some value even if it is ignored, which leads to code such as

Session session = connection.createSession(true,Session.AUTO_ACKNOWLEDGE);

Some developers like to use

Session session = connection.createSession(true,Session.SESSION_TRANSACTED);

though this is still misleading since since if transacted was set to true then the second argument is ignored anyway, and if transacted is false then setting acknowledgeMode to Session.SESSION_TRANSACTED would be an error.

In a Java EE transaction, both arguments are ignored anyway

In a Java EE transaction none of the four options listed above are permitted. Instead, both arguments to connection.createSession are ignored and a global transaction is used.

The EJB 3.1 Specification, section 13.3.5 "use of JMS APIs in Transactions" states that, in a container-managed or bean-managed transaction,

Because the container manages the transactional enlistment of JMS sessions on behalf of a bean, the parameters of the createSession(boolean transacted, int acknowledgeMode) method createQueueSession... are ignored.

This also applies to web applications. The Java EE platform spec, Section EE.6.7 "Java Message Service (JMS) 1.1 Requirements" specifies that

The behavior of a JMS provider should be the same in both the EJB container and the web container." It continues "The EJB specification describes restrictions on the use of JMS in an EJB container, as well as the interaction of JMS with transactions in an EJB container. Applications running in the web container should follow the same restrictions.

Instead, the receiving and sending of messages must be part of the container-managed or bean-managed transaction, and the transaction will be committed or rolled back in the way that container-managed or bean-managed transactions are committed or rolled back.

  • Container-managed transactions are either committed when the appropriate business method completes or are rolled back using EJBContext.setRollbackOnly.

  • Bean-managed transactions are either committed using UserTransaction.commit or rolled back using UserTransaction.rollback.

How explicit is the EJB specification about all this? In addition to specifying that in a transactional context the arguments to Connection.createSession are ignored, it also states the following:

  • Section 13.3.5 states that "within a transaction" the bean should not use the acknowledge method. This therefore covers both container-managed and bean-managed transactions.

  • Section 13.3.3 states that in the case of bean-managed transactions, the bean must not invoke the commit or rollback methods on the javax.jms.Session interface.

  • Section 13.3.4 states that in the case of container-managed transactions, the bean must not "use any resource-managed specific transaction management methods that would interfere with the container's demarcation of transaction boundaries" and again must not invoke the commit or rollback methods on the javax.jms.Session interface.

  • Section 13.1.1 states that in the case of bean-managed transactions, "all resource manager accesses between the UserTransaction.begin and UserTransaction.commit calls are part of a transaction", thereby apparently ruling out the use of non-transacted sessions using auto-acknowledgement and dups-ok-acknowledgement as well as those using client-acknowledgement.

  • Section 13.1.1 also states in a container-managed transaction the transaction demarcation depends on the transaction attributes of the bean method. It doesn't explicitly state that all resource manager accesses should be part of this transaction, but this is implied.

In a Java EE unspecified transaction context, the meaning of the arguments undefined and unclear

The previous section only relates to the use of the JMS API "in transactions". It does not cover how the JMS API should behave when there is no current container-managed or bean-managed transaction. That is, when there is an unspecified transaction context.

The EJB 3.1 Specification, section 13.6.5 "Handling of Methods that run with an unspecified transaction context" defines an "unspecified transaction context" as covering "the cases in which the EJB architecture does not fully define the transaction semantics of an enterprise bean method execution".

Section 13.6.5 goes on to give a list of examples of when an "unspecified transaction context" may arise. All the cases given are for container-managed transactions, leaving an ambiguity about what an "unspecified transaction context" means when using bean-managed transactions. An obvious interpretation is that that if a bean is configured to use bean-managed transactions, then business methods or onMessage() code executed before a call to userTransaction.begin(), or after a call to UserTransaction.commit or UserTransaction.rollback, is executed in an unspecified transaction context, as is any code executed in the four bean lifecycle callback methods listed in 13.6.5 (PostConstruct,PreDestroy, PostActivate, or PrePassivate). However this is not explicitly stated in the EJB spec.

So, what does the EJB spec say should happen in an "unspecified transaction context"?

Section 13.6.5 is written with all resource managers (not just JMS) in mind, and states that

"The EJB specification does not prescribe how the container should manage the execution of a method with an unspecified transaction context—the transaction semantics are left to the container implementation.

It goes on to give some options, which include treating "each call... to a resource manager as a single transaction", merging multiple calls into a single transaction, or accessing the resource manager "without a transaction context".

Now in the case of JMS the application has a way to give the container a hint as to what behaviour they desire: the arguments to {[createSession}}. So it would seem reasonable to follow these.

However the EJB 3.1 specification, section 13.3.5 does explicitly state that "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.

It is curious that although Session.acknowledge is prohibited in a unspecified transaction context, Session.commit is not, even though both perform message acknowledgement. If the former is invalid, then the latter must be as well.

This means that within an unspecified transaction context:

  • a non-transacted session using client acknowledgement is explicitly prohibited
  • a (local) transacted session is implicitly prohibited
  • a non-transacted session is permitted, with both client-acknowledgement and dups-ok-acknowledgement (which is an optimised version of auto-acknowledgement) allowed.

Summary

So in Connection.createSession (and QueueConnection.createQueueSession and TopicConnection.createTopicSession we have a method which offers different options depending on the context in which it is used:

  • In a Java EE transaction there are no options: the session is part of a transaction managed by the container and the application has no choice on the matter.

  • In a Java EE unspecified transaction context there are two options:

    • non-transacted session with auto-acknowledgement
    • non-transacted session with dups-ok-acknowledgement
  • In a Java SE environment there are four options:

    • non-transacted session with auto-acknowledgement
    • non-transacted session with dups-ok-acknowledgement
    • non-transacted session with client-acknowledgement
    • transacted session

So, in the light of all this, what are the problems?

  • the special behaviour of this method in a Java EE transaction is not mentioned anywhere in the JMS specification or in the javadocs, which means that users are surprised when they discover that the arguments to createSession are ignored. Fortunately, however, the required behaviour is clearly defined in the EJB specification.

  • the special behaviour in a Java EE unspecified transaction context is also not mentioned anywhere in the JMS specification or in the javadocs. Unfortunately, the required behaviour is not explicitly described in the EJB specification but has to be pieced together from various different sections, as in the analysis above. This needs to be confirmed and stated explicitly.

  • the actual API for createSession, with its two arguments, not only does not reflect the four options available in the normal Java SE case, it does not reflect the zero options available in the Java EE transaction case or the two options available in the Java EE unspecified transaction context case. However when compared the the two preceding issues this is perhaps not such a major issue.

Proposals

It is proposed that

  • The JMS specification and javadocs be updated to describe how createSession behaves in a Java EE applicaiton, both in a transaction and in an unspecified transaction context. The former case will be a restatement of the existing EJB spec, the latter case will be intended to remove any ambiguities in the EJB spec along the lines of the analysis above.

  • A new method be provided in a javax.jms.Connection

Session createSession(int sessionMode) throws JMSException

In a normal Java SE environment sessionMode may be set to 
Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE, Session.DUPS_OK_ACKNOWLEDGE 
or Session.TRANSACTED

In a Java EE transaction, sessionMode is ignored.

In a Java EE undefined transaction context, sessionMode may be set to 
Session.AUTO_ACKNOWLEDGE or Session.DUPS_OK_ACKNOWLEDGE only.
  • A further new method be provided in a javax.jms.Connection
Session createSession() throws JMSException

This method is  particularly intended for use in a Java EE environment,
though it may also be used in a normal Java SE environment.

In a normal Java SE environmentm this is equivalent to calling createSession(Session.AUTO_ACKNOWLEDGE)

In a Java EE transaction, the session will be part of a transaction managed by the container. 

In a Java EE undefined transaction context, the session will have a sessionMode of Session.AUTO_ACKNOWLEDGE.
  • The existing method createSession(boolean transacted,int acknowledgeMode will remain with a note added to encourage applications to use the other two methods. In accordance with Java EE policy it will remain in the API indefinitely, and will not be formally marked as @deprecated.

New API to send a message with async acknowledgement from server

This is a proposal for a new API which will send a message and return immediately without blocking until an acknowledgement has been received from the server. Instead, when the acknowledgement is received, an asynchronous callback will be invoked.

Here is a suggested API:

There would be a new method on javax.jms.MessageProducer:

public void setAcknowledgeListener(AcknowledgeListener listener);

This would change the behaviour of any subsequent call to any of the four send methods so that they would return without blocking until an acknowledgement has been received from the server. When the acknowledgement is received, the callback method on the AcknowledgeListener is received.

This feature will only be available for non-transacted sessions. if setAcknowledgeListener was called on a transacted session then a javax.jms.IllegalStateException would be thrown.

package javax.jms;
import javax.jms.Message;

public interface AcknowledgeListener {
	public void onAcknowledge(Message message);
}

Affected Versions

[1.1]

Clarify that JMS providers must implement both P2P and Pub-Sub

In the JMS Specification 1.1, Chapter 1.3 "What Is Required by JMS" says:

Providers of JMS point-to-point functionality are not required to provide publish/subscribe functionality and vice versa.

However Java EE 6 in Section EE.2.7.8 "Java™ Message Service (JMS)" says

The Java Message Service is a standard API for messaging that supports reliable point-to-point messaging as well as the publish-subscribe model. This specification requires a JMS provider that implements both point-to-point messaging as well as publish-subscribe messaging.

It is proposed to change the JMS specification to bring it in to line with Java EE, and make it mandatory for a standalone JMS provider to implement both point-to-point messaging (Queues) and publish-subscribe messaging (Topics).

Affected Versions

[1.1]

Fix JavaDocs to reflect missing NumberFormatException from API methods


NumberFormatException tests

For javax.jms.MapMessage and javax.jms.StreamMessage the JavaDoc's need to be updated for the string to numeric conversions. The String to numeric conversions must throw a
java.lang.NumberFormatException if the numerics valueOf() method does not accept the the String value as a valid representation.

Tests for (NumberFormatException) which is not listed in JavaDoc for the getXXX() methods. Test in question is: MapMessageConversionQTestsInvFormatString. The
(NumberFormatException) is mentioned in spec but missing in JavaDoc.

The JavaDoc's for the following methods below of class javax.jms.MapMessage and class javax.jms.StreamMessage need to be modified to add the NumberFormatException.

getBoolean, getByte, getShort, getInt, getLong, getFloat, getDouble, etc

Environment

N/A

Affected Versions

[1.1]

Specify that connection.stop() or close() may not be called from a MessageListener

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.

Support topic hierarchies

This issue was raised by a member of the JSR 343 Expert Group and is logged here to allow the issue to be discussed and tracked.

It is proposed that the JMS specification supports "topic hierarchies". These are also known as subject hierarchies or wildcard subscriptions.

The JMS 1.1 specification states that a topic is a "well-known node in a content-based hierarchy" but does not specify how this hierarchy is used, how topics are named, or define any special functionality to operate on more than one node of the hierarchy at the same time.

It is proposed that new features are added to JMS to explicitly support the use of topic hierarchies. More detailed proposals will follow: this JIRA issue is a placeholder.

Most JMS vendors and (and other pub/sub products) already support topic hierarchies, and they are integral to a variety of standards, including AMQP, Web Services Event Notification, and the Bayeaux protocol. They provide an intuitive solution for optimized message filtering, routing, and replication. Support for topic hierarchies would also be helpful for simplifying the integration of JMS applications into messaging environments that already depend on topic hierarchies.

Affected Versions

[1.1]

New "Not Before" Header

It would be nice to be able to filter out messages that shouldn't be consumed before a timestamp provided in a standard "not before" header.

I've heard before that at least one implementation provides a custom header for this use case, but can't find the reference now.

Affected Versions

[1.1]

New methods to replace Session.createDurableSubscriber() and return a MessageConsumer

In JMS 1.1 the following two methods on Session return a TopicSubscriber.

TopicSubscriber createDurableSubscriber(Topic topic)

TopicSubscriber createDurableSubscriber(Topic topic, java.lang.String name, java.lang.String messageSelector, boolean noLocal)

These are the only "domain-independent" methods in the whole JMS 1.1 API which depend on a "domain-specific" interface. This dependency prevents the "domain-specific" interfaces being removed from JMS as proposed in #47.

It is therefore proposed to modify these methods to return a MessageConsumer. Since this is a supertype of TopicSubscriber it should not break existing applications.

Affected Versions

[1.1]

Allow multiple consumers to be created on the same topic subscription

This proposal would allow multiple message consumers to be used to consume messages from the same durable or non-durable topic subscription. This would increase scalability by allowing messages from a topic to be processed by multiple consumers in a Java SE environment. Note that the existing JMS 1.1 API already allows this to be achieved for messages from a queue.

The multiple consumers might be in the same or different JVMs. Within the same JVM, the multiple consumers might use the same or different sessions and connection. Note, however, that the normal restrictions on the use of a session by multiple threads would continue to apply.

Durable subscriptions

For durable subscriptions, there would be no need to change the existing API. Applications would simply be allowed to create multiple consumers on the same durable subscription:

This affects the following JMS existing JMS 2.1 methods on Session (and its subtypes QueueSession, TopicSession, XASession, XAQueueSession and XATopicSession):

createDurableSubscriber(Topic topic, String name)
createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal)

It also affects the following JMS new JMS 2.0 methods on Session (and its subtypes QueueSession, TopicSession, XASession, XAQueueSession and XATopicSession) (added in JIRA issue 51 ):

createDurableConsumer(Topic topic, String name)
createDurableConsumer(Topic topic, String name, String messageSelector, boolean noLocal)

And in the new JMS 2.0 simplified API, it also affects the following method on JMSContext:

createDurableConsumer(Topic topic, String name)
createDurableConsumer(Topic topic, String name, String messageSelector, boolean noLocal)

All these methods currently have a restriction "Only one session at a time can have a TopicSubscriber for a particular durable subscription.". This restriction would be removed.

No change is proposed to the existing JMS requirement that only one connection may have a given clientID. This is defined in JMS 1.1 Section 4.4.3.2 "Client identifier", which states:

By definition, the client state identified by a client identifier can be 'in use' by only one client at a time. A JMS provider must prevent concurrently executing clients from using it.

This means that if a durable subscription is created by a connection with clientId set then it will not be possible to create a second consumer on it using a different connection.

However in JMS 2.0, clientId will become optional when creating a durable subscription (see JIRA issue 39). If a durable subscription is created by a connection with clientId unset then other connections may freely create further consumers on the same durable subscription.

This means that for two message consumers on different connections to share a durable subscription, clientId would need to be left unset.

In addition, the effect of using a different topic or message selector than was used when the subscription was first created needs to be amended. Currently this states (from the javadoc for Session.createDurableSubscriber):

A client can change an existing durable subscription by creating a durable TopicSubscriber with the same name and a new topic and/or message selector. Changing a durable subscriber is equivalent to unsubscribing (deleting) the old one and creating a new one.

This behaviour will continue, but only if there are no other active consumers on the durable subscription. If there is an active consumer on the durable subscription, and an attempt is made to create an additional consumer with a different topic or message selector, then a JMSException will be thrown (in the case of JMSContext a JMSRuntimeException will be thrown).

The semantics for the unsubscribe methods on Session and JMSContext would remain unchanged. The javadocs state that "It is erroneous for a client to delete a durable subscription while there is an active MessageConsumer or TopicSubscriber for the subscription". This will continue to be the case.

Non-durable subscriptions

For non-durable subscriptions, the JMS 1.1 specification specifies that if two non-durable TopicSubscribers are created on the same topic then two independent subscriptions are created: a copy of each message is sent to every consumer on that topic (with an appropriate message selector).

To allow two consumers to share the same subscription, so that they can share the load of processing messages from that subscription, then new API is required. To allow the consumers to specify that they wish to use the same non-durable subscription, they will need to specify the same sharedSubscriptionName.

The following new methods on Session (and its subtypes) are proposed:

MessageConsumer createSharedConsumer(
   Topic topic, String sharedSubscriptionName);
MessageConsumer createSharedConsumer(
   Destination destination, String sharedSubscriptionName, String messageSelector)
MessageConsumer createSharedConsumer(
   Destination destination, String sharedSubscriptionName, String messageSelector, boolean NoLocal)

Note that if these methods were called simply createConsumer there would be a clash with the existing method createConsumer(Destination destination, String messageSelector). Note that these methods take a Topic, not a Destination.

In the new simplified API, the following new methods on JMSContext are proposed:

JMSConsumer createSharedConsumer(
   Topic topic, String sharedSubscriptionName)
JMSConsumer createSharedConsumer(
   Topic topic, String sharedSubscriptionName, String messageSelector)
JMSConsumer createSharedConsumer(
   Topic topic, String sharedSubscriptionName, String messageSelector, boolean noLocal)

Note that a given shared subscription does not exist if there are no consumers using it.

Affected Versions

[1.1]

Last Value Cache Feature for a topic.

Add the Last Value Cache Feature for a topic.
When you will connect to a topic, the last message sent on the topic will be resent to the new client.

For instance, in the bank, without this feature, this JMS is generally not easily useable.
The common case is you want to publish price (bid/ask) on a stock. You have a topic by stock.
When a new client will connect to the topic, he will not receive a message until the price will move.

Affected Versions

[2.0]

New API to specify delivery delay

This issue was raised by members of the JSR 343 Expert Group and is logged here to allow the issue to be discussed and tracked.

This is a proposal to allow a JMS client to specify a delivery delay when sending a message. If a delivery delay has been specified for a message then the message will not be delivered to any consumers until after the delivery delay has expired.

This feature has also been referred to as "delivery time", "timed messages" or "future messages".

The API for delivery delay is intended to be similar to that for the existing timeToLive property of a MessageProducer and the corresponding JMSExpiration header field of a Message.

There would be new methods on javax.jms.MessageProducer:

public void setDeliveryDelay(long deliveryDelay) throws javax.jms.JMSException;

This sets the minimum length of time in milliseconds from its dispatch time 
that a produced message should be retained by the messaging system before 
delivery to a consumer. 

If the delivery delay is greater then the time to live then the message 
will always be expired before delivery.
public long getDeliveryDelay()

Returns the minimum length of time in milliseconds from its dispatch time 
that a produced message should be retained by the messaging system before delivery to a consumer.

There would be new methods on javax.jms.Message:

public long getJMSDeliveryTime() throws JMSException

Returns the message's delivery time. 

When a message is sent, the JMSDeliveryTime header field is left unassigned. 
After completion of the send or publish method, it holds the minimum delivery time time 
of the message. This is the sum of the delivery delay value specified by the client and 
the GMT at the time of the send or publish. 

When the delivery delay is specified as zero, JMSDeliveryTime is set to zero to indicate
that there is no delivery delay.

A provider must not deliver a message before the defined delivery time has been reached.
public void setJMSDeliveryTime(long deliveryTime) throws JMSException

Sets the message's delivery time.

JMS providers set this field when a message is sent. 
This method can be used to change the value for a message that has been received.

Note that this public method is not intended for use by clients but is needed to allow providers to set this value on a message implemented by a different provider. There is a separate issue to clarify this behaviour: #34

Affected Versions

[1.1]

Standard set of server JMX MBeans

A JMS implementation typically consists of one or more server processes.

As a monitoring client I would like to connect to these processes and discover a standard set of statistics (connections, queues, subscriptions, durables...) and for it to expose a standard set of administrative operations. such as JMS_SPEC_14,15,16 and 17.

Affected Versions

[1.1]

Clarify how the JMS provider should interact with Transaction Managers.

Clarify how the JMS provider should interact with Transaction Managers. In particular, the responsibilities of the JMS Provider, the TM and the App Server during recovery need to be clearly defined.

(This issue is a placeholder. More information about the ambiguities that need to be resolved will be added later)

Affected Versions

[1.1]

Make Connection and other interfaces implement AutoCloseable

This is a proposal to change all the JMS interfaces that currently implement a close() method to implement the java.lang.AutoCloseable interface?

This would affect Connection, Session, MessageConsumer, MessageProducer, QueueBrowser.

This is a new feature of Java SE 7 which makes it easier to write code which closes a resource after use.

There's a nice explanation here:
http://www.javacodegeeks.com/2011/07/java-7-try-with-resources-explained.html]

Briefly, it allows you to write code such as:

try { 
   Connection conn = connectionFactory.createConnection();
   Session sess = conn.createSession(false,Session.AUTO_ACKNOWLEDGE;
   MessageProducer producer = seession.createProducer(dest);
}{
   Message mess = sess.createTextMessage("hello");
   producer.send(mess);
} catch(JMSException e){
  // exception handling
}

When this code is executed, the close() methods on the connection, session and producer are always called after use.

  • There's no need to call close() on any of the objects that are created.
  • There's no need to provide a finally block containing the calls to close().
  • Objects are closed in the reverse order in which they were created.
  • There's no need to guard against calling close() on a null value.
  • There's no need to use a nested try/catch block within the finally block to catch exceptions thrown by close()
  • If the try() block throws an exception, and a subsequent call to close() throws a second exception as a consequence, then it is the first exception, not the second exception, that is passed to the catch block. So you only see the exception that really matters. Any suppressed exceptions can still be accessed from the thrown exception if needed.

This change would be of benefit to both Java SE and Java EE applications. The only drawback I can think of is that it would introduce a dependency on Java SE 7. This isn't an issue for Java EE 7 applications since these are already dependent on Java SE 7. But it would force Java SE applications to use Java SE 7. However by the time JMS 2.0 is released, in a year from now, Java 7 will be pretty widespread so this might not be a problem.

Affected Versions

[1.1]

change javadoc on session.createQueue and createTopic to make clearer the provider may create a physical destination

Most users have been asking us to add a flag to just create the server's side queue with some default values.

If I add the flag the configuration won't be spec compliant in some people's interpretation as the javadoc says the createQueue / createTopic is not for the physical creation itself.

I'm not sure what to make on the javadoc, the current version says this:

"Note that this method is not for creating the physical queue. The physical creation of queues is an administrative task and is not to be initiated by the JMS API. The one exception is the creation of temporary queues, which is accomplished with the createTemporaryQueue method."

My proposal is to change it to something permissive where the provider may or not create the physical queue. That would be a design choice.

Affected Versions

[1.1]

Add JMS defined property JMSXGroupLast

When grouping messages, there is no specified way to flag a message as the last one in a group.
To determine the last message in a group, one has to fall back to a vendor-specific property.
A good example can be found here: http://www.ibm.com/developerworks/websphere/library/techarticles/0602_currie/0602_currie.html

Adding a boolean JMS defined property with a name like JMSXGroupLast or similar would enable receiving group messages to be portable among different JMS providers.

Affected Versions

[2.0]

Deprecate domain-specific APIs and propose for removal

Summary

In version 1.0b of the JMS specification, applications had to use a completely separate set of interfaces when working with queues as they did when working with topics.

Specifically, applications working with queues had to use the interfaces QueueConnectionFactory, QueueConnection, QueueSession, QueueSender and QueueReceiver, whilst applications working with topics had to use the interfaces TopicConnectionFactory, TopicConnection, TopicSession, TopicPublisher and TopicSubscriber.

Although these two sets of interfaces shared common supertype interfaces ConnectionFactory, Connection, Session, MessageProducer and MessageConsumer, these were effectively abstract classes, and applications were forced to use the interfaces specific for the messaging domain (queue or topic) that they were using.

In version 1.1, new API methods were added to the common superclass, domain-independent, interfaces to allow them to be used directly by client applications. This offered a simpler programming model, and for first time allowed queues and topics to participate in the same local transaction, now that they could be accessed using the same session.

In JMS 1.1 all of the domain-specific interfaces were retained to provide backwards compatibility, but it was stated in Section 1.5 that "in the future, some of the domain-specific APIs may be deprecated".

For 2.0 it is time to take this to the next stage, and to formally announce that these interfaces are now deprecated and that they will be removed from a future version of the specification.

This would remove 15 interfaces from JMS and reduce the total number of interfaces by 34%, from 44 to 28.

Detail

This change would affect the following interfaces:

XAQueueConnection
XAQueueConnectionFactory
XAQueueSession
XATopicConnection
XATopicConnectionFactory
XATopicSession
QueueConnection
QueueConnectionFactory
QueueReceiver
QueueSender
QueueSession
TopicConnection
TopicConnectionFactory
TopicPublisher
TopicSession
TopicSubscriber

There would be two changes:

  • These interfaces would be formally marked as deprecated, by use of the @java.lang.Deprecated annotation. This would cause compilers to issue a warning when a deprecated method was used.

  • These interfaces would be formally marked in the specification as being "proposed for removal", with the expectation that they would be made optional in the next release.

There do not appear to be any binding policies on how to deprecate or remove classes from a Java EE API, which means that the final decision is up to the expert group. However the Java EE Specification, section EE.6.1.3 "6.1.3Pruned Java Technologies" (which discusses a different issue, that of removing entire technologies from Java EE), links to a Java SE policy described at http://mreinhold.org/blog/removing-features, which appears to be a suitable policy to offer.

That policy states that a particular version of a spec may state that a feature is "proposed for removal". This means that the following version can remove it.

However that policy also states that "removal" of a feature does not mean actually deleting it. Instead the feature will remain in the specification but will become optional. This means that implementers are not required to implement it. Its tests will remain in the TCK to allow those who decide to implement it to verify that it has been implemented correctly.

Other issues

Before making this change we should confirm that the "domain-independent" interfaces are a complete replacement for the "domain-specific" interfaces.

It has been noticed that Session.createDurableSubscriber() returns a TopicSubscriber, not a MessageConsumer. This looks to me like a mistake which would need to be fixed before we could remove TopicSubscriber. The solution would be for this method to return a MessageConsumer. Since this is a supertype of TopicSubscriber it should not break existing applications. (Edit: This has now been raised separately as #51 )

Add Reference to SOAP Binding

The W3C has developed an "official" SOAP binding for JMS that should probably be referred to by the next release of the spec.

Affected Versions

[1.1]

Support for Cloud Services

In addition to the vendors of on-premises software, we should hear from vendors of cloud services (like StormMQ) about any changes to the API that they think would make it easier to implement it.

Affected Versions

[1.1]

Durable subscription browser

Many if not all JMS providers give the ability to programmatically browse messages undelivered to a client on a durable subscription. Some do it via a custom API, some via JMX.

A standard way of doing this for all providers would make tooling easier.

Affected Versions

[1.1]

Allow JMS clients to specify whether a message is compressed in transit

This issue was raised by a member of the JSR 343 Expert Group and is logged here to allow the issue to be discussed and tracked.

This is a request to allow JMS clients to define whether a message is compressed in transit, perhaps on a per-message basis or more globally.

JMS providers are currently free to decide for themselves whether to compress a message, and many do, so the question here is whether it is desirable to allow clients to control this via the API rather than via provider configuration features.

Affected Versions

[1.1]

Support for STOMP messaging

Just like with AMQP in #9, the STOMP protocol should be taken into consideration in the next release of the spec.

It should continue to be a goal of this specification, though, to make it easier to implement the API on top of whatever wire protocol is chosen by the vendor.

Affected Versions

[1.1]

Make clientId optional when creating a durable subscription

(There was a change of mind on this issue. Initially this feature was added for both JMS 1.1 unshared subscriptions as well as JMS 2.0 shared subscriptions but we changed our mind and in the end it was added for JMS 2.0 shared subscriptions only. This note was added retrospectively to make this issue easier to understand when reading it.)

This is a proposal to make clientId optional when creating a durable subscription

In JMS 1.1, a durable subscription is defined by the combination of clientId and subscriptionName. Section 6.11.1 of the Specification states:

Sessions with durable subscribers must always provide the same client
identifier. In addition, each client must specify a name that uniquely identifies
(within client identifier) each durable subscription it creates.

Whilst it is clear that a durable subscription needs to have a name to allow it to be identified, it is less clear why it needs to be identified by clientId. This is the only place in the JMS API where a connection must have clientId set.

This requirement to have clientId set causes complication for applications, especially in a Java EE application, where clientId must be set on the connection factory. This means that the connection factory can only be used to create a single instance, and if a connection pool is used it must be constrained to allow only a single instance.

It is therefore proposed that the use of clientId be made optional when creating a durable subscription. In this case, the subscription will be defined by the name of the subscription alone.

This change is not intended to change the existing restrictions stated in Section 6.11.1:

Only one session at a time can have a TopicSubscriber for a particular durable subscription.

Affected Versions

[1.1]

Support for pre-acknowledge ack mode

Many messaging systems allow messages to be automatically acknowledged on the server before they are delivered to their consumers. This feature is useful for transient messaging use cases where it does not matter if some messages are lost on failure (e.g. stock pricing information).

JMS does not currently provide an acknowledgment mode which supports pre-acknowledgment on the server, so there's extra (unnecessary) traffic due to acks having to be sent from client--server.

In reality most JMS implementations provide pre-ack as an extension to the set of JMS ack modes. I would like to propose that pre-ack is added to the list of standard ack modes in JMS.

Affected Versions

[1.1]

Message producer confirms aka async message production.

The synchronous 1.1 JMS API has an impact on how a single thread can produce messages with a session. There is too much waiting around for a reply from the server.

As a JMS client I would like to send a message on a non-transacted session with persistent delivery and receive asynchronous confirmation that it is stable via a callback. The session can then interact with the server in a more efficient manner.

RabbitMQ has a good write up of the functionality http://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms.
29West and Tervela have similar capability.
No doubt some JMS implementations have similar capabilities using non-JMS APIs.

Affected Versions

[1.1]

Improve specification of ExceptionListener

The use of a ExceptionListener is described in the JMS 1.1 specification in section 4.3.8 "ExceptionListener":

If a JMS provider detects a problem with a connection, it will inform the connection's ExceptionListener, if one has been registered. To retrieve an ExceptionListener, the JMS provider calls the connection's getExceptionListerer()
method. This method returns the ExceptionListener for the connection. If no ExceptionListener is registered, the value null is returned. The connection can then use the listener by calling the listener 's onException() method, passing it a JMSException describing the problem.

This allows a client to be asynchronously notified of a problem. Some connections only consume messages, so they would have no other way to learn their connection has failed.

A Connection serializes execution of its ExceptionListener.

A JMS provider should attempt to resolve connection problems itself prior to notifying the client of them.

The exceptions delivered to ExceptionListener are those that have no other place to be reported. If an exception is thrown on a JMS call it, by definition, must not be delivered to an ExceptionListener (in other words, ExceptionListener is not for the purpose of monitoring all exceptions thrown by a connection).

Despite this, there have been a number of questions about the use of an ExceptionListener. These questions are listed below, together with proposed answers. It is proposed that the answers to these questions be incorporated into the specification.

Question 1: When Connection.stop() or Connection.close() is called, must these methods wait until any active calls to ExceptionListeners for that connection have returned, in the same way that they must wait until any active call to MessageListeners have returned?

Proposed answer: No.

Question 2: Is there any restriction on the use of Connection.stop() or Connection.close() from an ExceptionListener?

Proposed answer: No.

Question 3: What does "a Connection serializes execution of its ExceptionListener" mean?

Proposed answer: This means that if a connection encounters multiple problems and therefore needs to call its ExceptionListener multiple times, then it will only invoke onMessage() from one thread at a time. Note however that if the same ExceptionListener is registered with different connections then it is undefined whether these connections could call onMessage() from different threads simultaneously.

Question 4: What is the effect of ExceptionListener.onException() being slow or blocking?

Proposed answer: This is undefined. There is no requirement that any other operation need block until ExceptionListener.onException() has return, apart from other calls to ExceptionListener.onException() for the same connection.

Affected Versions

[1.1]

Make support for JMSXDeliveryCount mandatory

This issue was raised by a member of the JSR 343 Expert Group and is logged here to allow the issue to be discussed and tracked.

It is proposed that support for the JMS defined message property JMSXDeliveryCount be made mandatory.

The JMS 1.1 specification currently defines an optional JMS defined message property JMSXDeliveryCount. When used, this is set by the JMS provider when a message is received, and is set to the number of times this message has been delivered (including the first time). The first time is 1, the second time 2, etc.

Support for this property would allow arbitrary containers and applications to improve the way they handle "poisonous" messages - messages which cannot be consumed for some reason and need to be redelivered. For example, it would allow applications to detect when a message has been redelivered more than a specified number of times and perform some special handling such as redirecting it to some other destination.

This property wouldn't need to be perfectly accurate every time. For example, it wouldn't be necessary to persist this value in the server. A "best efforts" implementation would probably be adequately.

Affected Versions

[1.1]

Improving the JMS API with API simplifications, annotations and CDI

We should provide a modern, easier-to-use API, probably using annotations and CDI. There seemed to be a variety of ideas of how we might do this, and we will need to explore these in detail. Whilst I think we mostly see this as a feature for Java EE containers, there seems to be interest in offering features to those using a Java SE environment as well.

(This issue is a placeholder for discussion on the JSR 343 EG. More information will be added later)

Affected Versions

[1.1]

Provide HTTP Binding

If none is available from another organization, I think the JCP should provide (maybe in a separate JSR) a standard HTTP binding for JMS, given how often these technologies are used together.

Affected Versions

[1.1]

Add Reference to URI Scheme

The IETF has published an "official" URI scheme for JMS that should probably be referred to by the next release of the spec.

Affected Versions

[1.1]

Multi-Value Support in Properties

It is desirable to be able to store multiple values with the same key in a JMS message, like in a HTTP request, for example.

Environment

All JMS environments

Affected Versions

[1.1]

Properties on Messages should follow builder pattern.

Currently, methods such as javax.jms.Message.setBoolean return void. However, in recent years the builder pattern has grown in adoption, allowing developers to chain method calls by having the method return the object that the method was performed upon. If the property methods return these objects, then the code would look much cleaner.

Queue Depth

As a client I would like to get the current queue depth on a queue. All existing providers give this information via a custom API or JMX at present.

Affected Versions

[1.1]

Decide on the future of the optional Chapter 8 API "JMS Application Server Facilities"

Chapter 8 of the JMS 1.1 specification, "JMS Application Server Facilities", defines an API for use by application servers. It has two parts:

  • API to allow concurrent processing of a subscription's messages: the interfaces ServerSession, ServerSessionPool, ConnectionConsumer and the methods Session.setMessageListener(), Session.getMessageListener() and Session.run().

  • API to support distributed (XA) transactions: XAConnectionFactory, XAConnection and XASession.

This API is optional and has no compliance tests.

Should this API be made mandatory, like the rest of the JMS spec, or should it be formally pruned from the spec?

This will partly depend on the outcome of http://java.net/jira/browse/JMS_SPEC-25 (Standardise the interface between a JMS provider and a Java EE application server). If it is decided that the interface between a JMS provider and a Java EE application server should use these interfaces (rather than the Java EE Connector API) then clearly they should become mandatory.

However, irrespective of the outcome of http://java.net/jira/browse/JMS_SPEC-25 it may be beneficial to keep this API and make it mandatory since that would

1. allow the creation of a generic JMS resource adapter that can work with any JMS 2.0 implementation, and
2. allow the creation of non-Java EE frameworks that provide services such as XA transactions and async delivery to multiple consumers, but which don't support the Java EE Connector Architecture

However these potential benefits need to be offset against the additional burden this may place on JMS vendors.

Note that if it is decided that these interfaces are not needed, they would not be deleted from the spec but remain in their current optional state, in accordance with chapter EE.6.1.3 "Pruned Java Technologies" of the Java EE 6 specification, perhaps with an explicit statement of why they are not needed.

If it is decided that these interfaces are still required then there some improvements may be required to clarify, say, the integration with the transaction manager.

Standardise the interface between a JMS provider and a Java EE application server

We need to standardise the interface between a JMS provider and a Java EE application server, to allow portability of JMS providers between application servers.

The frontrunner here is to mandate the provision of a JCA resource adapter, though an alternative may be to extend and make mandatory the existing Chapter 8 API.

Affected Versions

[1.1]

Clarify that a message may be sent using a different session from that used to create the message

The JMS 1.1 API defines how a JMS message object is created using one of the following methods on a Session:

Message 	createMessage() 
BytesMessage 	createBytesMessage() 
MapMessage 	createMapMessage() 
ObjectMessage 	createObjectMessage() 
ObjectMessage 	createObjectMessage(java.io.Serializable object) 
StreamMessage 	createStreamMessage() 
TextMessage 	createTextMessage() 
TextMessage 	createTextMessage(java.lang.String text)

The following question has been raised:

Can a message be sent using a MessageProducer that was created from a different Session than was used to create the message?

This is not stated explicitly in the specification, and discussions within the JSR 343 Expert group show that different individuals have come to different conclusions on this issue.

My own interpretation is that a MessageProducer must be able to send a javax.JMS.Message irrespective of how it was created. It might have been created using Session.createMessage(), or it may have been received by a MessageConsumer.

Section 4.4.5 "Optimized message implementations" of the JMS 1.1 specification states:

A session provides message create methods that use provider-optimized implementations. This allows a provider to minimize its overhead for handling messages.
Sessions must be capable of sending all JMS messages regardless of how they may be implemented.

Furthermore, Section 3.12 of the JMS 1.1 specification states explicitly that a MessageProducer must be able to send a message that was created using a different JMS provider, and which would therefore have used a different session:

A provider must be prepared to accept, from a client, a message whose implementation is not one of its own. A message with a 'foreign' implementation may not be handled as efficiently as a provider's own implementation; however, it must be handled.

Despite this, there is a widespread view within the JMS community that for messages created within the same JVM by the same JMS provider, the session used to create the message must be the same as that used to send it.

It is therefore proposed that the JMS specification be clarified that there is no such restriction, and that a MessageProducer can be used to send any message object

  • irrespective of which session or connection was used to create it,
  • irrespective of whether the message was created within this JVM or received from a JMS destination, and
  • irrespective of whether the MessageProducer and message are implemented by the same or different JMS providers.

Affected Versions

[1.1]

Fix JavaDocs to reflect missing IllegalStateException from API methods

IllegalStateException tests

The JavaDocs for the following methods below need to be updated to reflect that IllegalStateException can be thrown. In particular IllegalStateException is being thrown in the case of these methods being called on closed connection objects. There could be more methods than those listed below.

javax.jms.QueueSession.commit}}  
    javax.jms.QueueSession.getTransacted  
    javax.jms.QueueSession.rollback 
    javax.jms.QueueSession.recover
    javax.jms.QueueConnection.getClientID
    javax.jms.QueueConnection.getMetaDataTest
    javax.jms.QueueConnection.createQueueSession
    javax.jms.QueueConnection.start
    javax.jms.QueueSession.createBrowser(*)
    javax.jms.QueueSession.createQueue
    javax.jms.QueueSession.createSender()
    javax.jms.QueueSession.createTemporaryQueue()
    javax.jms.QueueSession.createMessage()
    javax.jms.QueueSession.createBytesMessage()
    javax.jms.QueueSession.createMapMessage()
    javax.jms.QueueSession.createObjectMessage(*)
    javax.jms.QueueSession.createStreamMessage()
    javax.jms.QueueSession.createTextMessage(*)
    javax.jms.QueueSession.createStreamMessage()
    javax.jms.QueueReceiver.getMessageSelector()
    javax.jms.QueueReceiver.receive(*)
    javax.jms.QueueReceiver.receiveTimeout()
    javax.jms.QueueReceiver.receiveNoWait()
    javax.jms.QueueReceiver.getQueue()
    javax.jms.QueueSender.getDeliveryMode()
    javax.jms.QueueSender.getDisabledMessageID()
    javax.jms.QueueSender.getDisabledMessageTimeStamp()
    javax.jms.QueueSender.getPriority()
    javax.jms.QueueSender.getTimeToLive()
    javax.jms.QueueSender.setDeliveryMode()
    javax.jms.QueueSender.setDisabledMessageID()
    javax.jms.QueueSender.setDisabledMessageTimeStamp()
    javax.jms.QueueSender.setPriority()
    javax.jms.QueueSender.setTimeToLive()
    javax.jms.QueueSender.getQueue()
    javax.jms.QueueSender.send(*)
    javax.jms.TopicSession.commit  
    javax.jms.TopicSession.rollback 
    javax.jms.TopicSession.recover
    javax.jms.TopicSession.createTopic
    javax.jms.TopicSession.createSubscriber(*)
    javax.jms.TopicSession.createDurableSubscriber(*)
    javax.jms.TopicSession.createPublisher()
    javax.jms.TopicSession.createTemporaryTopic()
    javax.jms.TopicSession.unsubscribe()
    javax.jms.TopicSession.createMessage
    javax.jms.TopicSession.createBytesMessage
    javax.jms.TopicSession.createMapMessage
    javax.jms.TopicSession.createObjectMessage
    javax.jms.TopicSession.createStreamMessage
    javax.jms.TopicSession.createTextMessage
    javax.jms.TopicSession.getTransacted
    javax.jms.TopicSubscriber.getMessageSelector
    javax.jms.TopicSubscriber.receive(*)
    javax.jms.TopicSubscriber.receiveNoWait()
    javax.jms.TopicSubscriber.getNoLocal()
    javax.jms.TopicSubscriber.getTopic()
    javax.jms.TopicConnection.getClientID
    javax.jms.TopicConnection.getMetaDataTest
    javax.jms.TopicConnection.start
    javax.jms.TopicConnection.createTopicSession
    javax.jms.TopicPublisher.getDeliveryMode()
    javax.jms.TopicPublisher.getDisabledMessageID()
    javax.jms.TopicPublisher.getDisabledMessageTimeStamp()
    javax.jms.TopicPublisher.getPriority()
    javax.jms.TopicPublisher.getTimeToLive()
    javax.jms.TopicPublisher.setDeliveryMode()
    javax.jms.TopicPublisher.setDisabledMessageID()
    javax.jms.TopicPublisher.setDisabledMessageTimeStamp()
    javax.jms.TopicPublisher.setPriority()
    javax.jms.TopicPublisher.setTimeToLive()
    javax.jms.TopicPublisher.getTopic()
    javax.jms.TopicPublisher.publish(*)

Tests for IllegalStateException

The JavaDocs should be updated for all of the above method calls to specify that an IllegalStateException can be thrown on closed connection objects. Currently it doesn't. Only the JMS spec specifies that IllegalStateException must be thrown. The JavaDoc should be in sync with the spec and should mention it as well.

The JMS spec references for this is in the following sections:

  • 4.3.5 Closing a Connection
  • 4.4.1 Closing a Session
  • 4.11 Method Inheritance across Messaging Domains
  • Table 4-1 Methods That Must Throw an IllegalStateException
  • 7.3 Standard Exceptions
  • 11.2.21 JMS Source Java API documentation Clarifications
  • Table 11-2 Domain Dependent Interfaces

The CTS JMS test directories which are testing for IllegalStateException to be thrown on closed QueueConnection, closed QueueReciever, closed QueueSender, etc. objects are listed below:

jms/ee/all/closedQueueConnection
    jms/ee/all/closedQueueReceiver
    jms/ee/all/closedQueueSender
    jms/ee/all/closedQueueSession
    jms/ee/all/closedTopicConnection
    jms/ee/all/closedpublisher
    jms/ee/all/closedsubscriber
    jms/ee/all/closedtopicsessiontests

Environment

N/A

Affected Versions

[1.1]

New JMS header type: a Set

As a JMS client I would like to populate a set in the message header and have it take part in selectors. The set would be generic somehow and the filter expressions available would "contains" and "not contains"

I cannot come up with a good looking API change to the Message interface to allow this set to be manipulated cleanly other than getStringHeaderSet, getDoubleHeaderSet etc. There must be a better way, perhaps via a builder pattern.

What I really would find useful is the selector:

"MyProperty contains 'AAA' or MyProperty contains 'BBB'"

Use Case:

Consider a multi national orgianisation with many offices (legal entities) and therefore many back office systems and they are all connected via messaging. A single "deal" can span many offices and many clients. When the deal has been agreed a notification would be sent with a "header set" containing all the offices involved in the deal with each back office subscribing to deals where it is a participant and therefore its identifier is in the header set.

Topics and wild carding do not work in this scenario as the number of participating offices is variable.

Affected Versions

[1.1]

Clarify the relationship between the JMS and other Java EE specifications

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.

Affected Versions

[1.1]

Durable subscription iterator

As a monitoring client I would like to list all the durable subscriptions the login is permissioned to see., i.e. the clientID, durableName and any selector.

Affected Versions

[1.1]

Remove the use of unchecked exceptions from the JMS API as far as possible

In JMS 1.1, almost every method in the JMS API throws a javax.jms.JMSException, which is a checked exception and so needs to be caught and handled by the application.

In practice the developer rarely knows what to do in such circumstances, and provides some generic exception handling that is not specific to JMSException. The result is to clutter the application code with boilerplate exception handling which adds little value.

In addition, the fact that so many API methods throw this checked exception makes it more difficult to construct frameworks on top of the JMS API.

It is therefore proposed that the JSR 343 Expert Group consider whether they should change the JMS API to throw unchecked rather than checked exceptions as much as possible. One simple way of achieving this would be to change javax.jms.JMSException to extend java.lang.RuntimeException instead of java.lang.Exception.

Existing applications which explicitly catch JMSException would not need to be changed.

Affected Versions

[1.1]

Allow messages to be delivered asynchronously in batches

It is proposed that the JMS API be extended to allow messages to be delivered to a MessageListener in batches rather than individually as in JMS 1.1.

Currently, messages are delivered asynchronously by calling the javax.jms.MessageListener method onMessage(Message message).

However some applications could process messages more efficiently if they were delivered in batches. Applications would define a new listener class javax.jms.BatchMessageListener with a callback method onMessages(Message[] messages).

It would be necessary to configure this by adding a new method to javax.jms.MessageConsumer:

void setBatchMessageListener(BatchMessageListener listener, int batchSize, long batchTimeOut)

Sets the message consumer's batch message listener. Attempting to set both a message listener and a batch message listener on the same MessageConsumer would cause a javax.jms.IllegalStateException.

  • listener The BatchMessageListener being set

  • batchSize If set to a value greater than zero, messages will be delivered in batches of up to batchSize messages. The actual batch size used may be smaller than this, but it may never be larger.

  • batchTimeOut The maximum number of milliseconds that the JMS provider may defer message delivery for in order to assemble a batch of messages that is as large as possible but no larger than the batch size.

Acknowledgement:

  • If auto-acknowledgement was being used, all messages in the batch would be acknowledged together. Section 4.4.12 "Duplicate Delivery of Messages" of the JMS 1.1 spec explains that when auto-acknowledgement is being used, if a failure occurs, clients can't know for sure whether the message has been successfully acknowledged, and so the last consumed message may may be redelivered. This section would need to be extended to state that in the case of batch delivery, if a failure occurs, all messages in the last batch may be redelivered.

  • If dups-ok acknowledgement was being used, message acknowledgement would follow existing semantics.

  • If client acknowledgement, or local or global transactions, were being used then message acknowledgement would follow existing semantics, which is that a call to acknowledge(), or the commit of the transaction, would acknowledge all unacknowledged messages delivered by the session.

Affected Versions

[1.1]

Allow and specify clustered durable subscribers

The current specification arguably disallows clustering durable subscibers by the following wording: "Only one session at a time can have a TopicSubscriber for a particular durable subscription."

At least one JMS provider (WebSphereMQ) allows multiple TopicSubscribers to the same durable subscription. The subscribers themselves basically act like receivers for a queue.

This feature helps avoiding a single point of failure.

Affected Versions

[2.0]

Clarify classloader used in ObjectMessage.getObject() and/or provide new method getObject(ClassLoader classLoader)

It is specified neither in the spec nor in the API JavaDoc which ClassLoader is to be used, when the object gets deserialized in ObjectMessage.getObject().
This omission lead to different implementations (and bugs) among JMS providers, as can be seen here:
http://www-01.ibm.com/support/docview.wss?uid=swg1IC72855
http://www.coderanch.com/t/313402/EJB-JEE/java/Exception-receiving-ObjectMessage-JMS
http://forums.oracle.com/forums/thread.jspa?threadID=738545
http://community.jboss.org/message/437144#437144

Alternatively, if it isn't possible to specify the class loader, add a method "Serializable getObject(ClassLoader classLoader) to ObjectMessage.

Affected Versions

[2.0]

Calling setJMSDeliveryMode or setJMSPriority on a javax.jms.Message before it is sent don't have any effect

This issue relates to the following methods on javax.jms.Message:

setJMSPriority
setJMSDeliveryMode

Many novice developers think these methods can be used to set the priority and delivery mode of a message before it is sent. In fact these methods have no effect: the only way to set priority and delivery mode is by using methods on javax.jms.MessageProducer.

This a common cause of confusion to developers. Can we either deprecate these methods or else change them so that actually do something?

Affected Versions

[1.1]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.