Hello All,
Nigel and I work closely together at Oracle. I've listed a variety of items below that expand on Nigel's priority list, but personally don't expect that it'll be practical to get them all into JMS 2.0. I hope that items that don't make the cut, but that still have substantial EG interest, will eventually wend their way into future JMS JSRs.
I tried to mark ideas that have already been discussed by other JSR-343 folks as "+1".
Cheers!
Tom
***************************
*** Highest Priorities: ***
***************************
In no particular order:
# (+1 to existing proposal for) a modern, easier-to-use API, with annotation & CDI goodness.
# (+1 to existing statement that) we don't lose sight of the need to be able to use the JMS API outside of a Java EE environment. Java EE must not be a requirement. Java EE and SE JMS behavior and API should be as similar as possible.
# Support topic hierarchies (also known as subject hierarchies or wildcard subscriptions). IIRC, some vendors map topic hierarchy nodes to subscriptions on a single topic, while others map each node to an entire topic (eg, a hierarchy of topics). Topic hierarchies provide an intuitive solution for optimized message filtering, routing, and replication. Support would also be helpful for simplifying the integration of JMS applications into messaging environments that already depend on topic hierarchies (the mapping into and out of the JMS API becomes more straight forward). 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.
# Support shared topic subscriptions. The idea is to support multiple concurrent message consumers from different sessions on the same durable or non-durable subscription. This would allow applications to use multiple threads to consume messages from the same topic subscription using the vanilla javax.jms.* API, offering much greater scalability.
# Make support for the JMSXDeliveryCount message property mandatory (this is optional in JMS 1.1). This wouldn't need to be perfectly correct -- a "best effort/volatile" implementation would probably be adequate -- but support for it would allow arbitrary containers and applications to more easily detect problem messages and handle them accordingly.
# Provide a mandatory API that (1) would allow the creation of a generic JMS resource adapter that can work with any JMS 2.0 implementation, and (2) would allow the creation of non-Java EE frameworks that provide services such as XA transactions and resource pooling, but which don't support the Java EE Connector Architecture. One specific advantage of (1) is that it allows vendors to provide a generic JMS resource adapter which can be configured, managed and monitored in the same way regardless of JMS provider. The mandatory API could probably be based on the existing JMS 1.1 Chapter 8 API (XAConnection, XASession, ConnectionConsumer etc), with some changes to resolve gaps in the existing API, plus perhaps a simplification involving replacing XAConnectionFactory, XAConnection and XASession with a new method getXAResource() on Session.
# Clarify the specification to state that support for XA transactions should work with any JTA transaction manager and not be restricted to a transaction manager supplied by the vendor.
*************************************
*** Lower priorities: API changes ***
*************************************
In no particular order:
# (+1 to existing proposal for) API to asynchronously send a message, with the server invoking a callback to acknowledge receipt.
# New API to asynchronously receive a single message.
# New API to asynchronously perform client acknowledgement, with the server invoking a callback to acknowledge receipt of the acknowledgement.
# New API to asynchronously commit a local transaction, with the server invoking a callback to acknowledge receipt of the commit.
# New method close() on javax.jms.Message, after which the message body and properties could not be accessed. This would allow vendors to optionally reclaim the memory used to hold the message body and properties.
# New API for client acknowledgement. The current API currently acknowledges the receipt of all messages that have been delivered by the session. Provide two variations: to acknowledge a single message only, and to acknowledge all messages delivered by the session up to and including a given message.
# (+1 to existing proposal for) scheduled future message delivery.
# Define standard behavior for the handling of problem (or "poison") messages by a MessageListener or MDB. These are messages which the consuming application cannot process for some reason and which need to be redelivered.
## Clarify how the application should reject such messages (e.g. what exception should be thrown, for both Java SE MessageListener and MDB). For MDBs, define a simple way for non-transactional MDB to force a redelivery (IIRC: this currently requires throwing an arbitrary Runtime, and the container is in turn required force a call a recover, and destroy the bean -- I think this is impractical/inefficient).
## Allow an "error destination" to be defined (e.g. in a message header), to where a message is sent after a defined number of unsuccessful redeliveries. Note that making JMSXDeliveryCount mandatory would make it easier for this to be done by frameworks and RAs and lessen the need for error destination standardization.
# Investigate whether it's possible to change javax.jms.Session.unsubscribe(java.lang.String subscription-name) to require javax.jms.Topic as an additional parameter. Theoretically, Topic isn't needed since the subscription-name and client-id (obtained from the connection) should be sufficient to uniquely identify a subscription.
However:
## Some JMS providers may not enforce client-id uniqueness, which would allow two subscriptions to be created with the same client-id and subscription-name. Furthermore, we may choose to relax the JMS specification client-id requirement to enable support for shared subscriptions in JMS 2.0. In these cases, the existing javax.jms.Session.unsubscribe(java.lang.String subscription-name) is inadedequate to uniquely identify the subscription.
## In addition, the current API forces providers of clustered messaging solutions to maintain a global table of <client-id, topic-name, subscription-name>, which may be complex for some vendors and is less scalable. (To maintain the required degree of backwards compatibility it may be necessary simply to add a new method and deprecate the existing method with the goal of removing it in a future release of the spec). Do other EG members see a need for any of this?
# Clarify the spec requirement for client-id uniqueness. The JMS 1.1 spec is (arguably) less than explicit as to whether a JMS provider must enforce the uniqueness of client-id. The spec should be made more explicit as to whether the enforcement of unique client-id is mandatory. One possibility might be to drop the concept of client-id completely (and modify the spec for durable subscriptions accordingly). Note that client-id uniqueness enforcement conflicts with the above "shared topic subscription" goal: shared subscriptions may need to support multiple connections with the same client-id so that their respective consumers can all attach to the same subscription (subscriptions are currently identified via client-id and subscription-name).
# (+1 to existing proposal to) Improve existing API method Connection.createSession(boolean transacted, int acknowledgeMode). An additional idea not mentioned so far is to have a single arg with options auto-ack, dups-ok-ack, client-ack, local-tx, and global-tx. The global-tx option would allow applications in a web or EJB container to explicitly specify whether they should participate in the global transaction (which they can't control at present). Whether or not we adopt such a flag, we should also consider whether we can clarify what should happen when in a web or EJB container when there is no transactional context - this is currently left to the container to decide.
# (+1 to existing proposal to) standardize the MDB activation config properties and other MDB API. In addition, add a property to specify maximum MDB concurrency - eg, provide direct control over the maximum number of concurrent message processing threads (override max-beans-in-free-pool).
# Support passing Message Header ReplyTo destinations between vendors as an opaque serialized object. Currently, JMS vendors must null out the ReplyTo field when it references a foreign vendor's destination.
# Define standard C and .NET APIs to JMS providers, possibly via a spin-off (non-JCP?) organization.
# To help ensure application portability, clarify the role of JNDI for obtaining administered objects (connection factories and destinations). In theory, a JMS provider's administered objects may be bound into a JNDI provider and retrieved via a JNDI lookup. The JMS 1.1 Spec (Section 4.2) and ConnectionFactory javadoc state: "JMS provider implementations of administered objects should be both javax.naming.Referenceable and java.io.Serializable so that they can be stored in all JNDI naming contexts." The CTS tests should be extended to ensure this.
# Provide a javax.jms API for the creation of administered objects from client code.
*********************************************
*** Lower priorities: QoS Rationalization ***
*********************************************
I think it would be helpful to standardize QoS/performance related behaviors to ensure application portability, and to ensure that average developers understand the quality-of-service that they're getting. For example, in no particular order:
# Define more precisely the expected QoS of non-persistent messages. This should allow vendors to know whether a message send should block until it receives an acknowledgement from the server, and perhaps offer new API which allows applications to choose which they require. It would also allow applications to have a better idea of the expected QoS (if a non-blocking send appears to succeed, this is not necessarily an indication that the message will actually make it all the way to the target destination).
# Define more explicitly when an internal acknowledgement should occur when calling receive() in auto-ack mode. The spec suggests that the ack and consequential message delete should complete before receive() returns control to the caller, although this leaves a window where a client crash could effectively cause a lost message. Some vendors (I believe) send the ack on the next call to receive(), which provides a potential performance optimization, protection against lost messages, and is arguably closer to the auto-ack behavior expected for asynchronous consumers. Should the spec allow this, perhaps as an option?
# Consider adding a specification section that helps educate average developers that they may need to take special action to attain their desired QOS from typical messaging systems. The section could define terminology, and could describe the possible variance in "out-of-the-box" QOS behavior between different providers. For example, can we help users understand how to tune various messaging environments to prevent lost messages in the event of typical hard failures, such as an operating system crash, power loss, or network failure? The OSG SpecJMS rules include some discussion in this area.
# Clarify whether it is spec compliant to send a persistent message to a consumer before the message has been persisted/queued/committed. IMO, this behavior should only manifest if an application specifically requests it. Additional thoughts:
## In detail, this behavior allows consumers to receive a message before it's safely persisted, queued, and/or committed but perhaps only when explicitly requested by the producer.
## The behavior can be made safer if, when the receive transaction fails, either (A) the send transaction somehow also fails with a thrown Exception into the application, or (B) the send blocks until it's persist/commit succeeds so that the message can be redelivered later.
## I think that this is an interesting (and relatively simple to implement) optimization, but that the behavior is different enough from expectations that it yields non-portable behavior. As an example of non-portable behavior, an application that tries to receive a specific message that it just sent from within the same transaction will dead-lock on (most?) JMS vendors.