users@jms-spec.java.net

[jms-spec users] [jsr343-experts] Re: (JMS_SPEC-40) Allow multiple threads in same client to consume messages from the same topic subscription

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Tue, 03 Apr 2012 16:43:26 +0100

Rob,

Thanks for the instant response! (I realise you weren't on the EG when this first came up, and I appreciate your
comments now)

One of the goals of JMS 2.0 (and indeed Java EE 7 generally) is to allow applications written to work with JMS 1.1 to be
used with JMS 2.0 without any need to change the code. The backward compatibility rules for Java EE 7 can be found at
http://java.net/projects/javaee-spec/pages/CompatibilityRequirements

However there may be cases where something that caused an error with 1.1 will be allowed in 2.0. For example, the
requirement to set ClientID when creating a durable subscription has been removed in JMS 2.0 (and is in the Early
Draft). I judged that this would not break existing applications though strictly speaking it does represent a change in
behaviour. The change proposed below for durable subscriptions would be similar: creating a second active consumer on an
existing durable subscription was forbidden in 1.1 but would be allowed in 2.0. (The change for non-durable
subscriptions involves a completely new API and doesn't raise this issue).

Now you raise the interesting issue of existing clients, using the same JMS 1.1 provider client as they do now,
connecting to a new JMS 2.0 server. Supporting two different JMS provider client versions at the same time is a
different use case and not something that JMS (or the backwards compatibility rules) has ever said anything about. But
it seems a reasonable thing for vendors to want to offer.

It seems to me that where a JMS 1.1 client connects to a JMS 2.0 server (for those providers which allow this) then it's
up to the JMS vendor to decide what behaviour to offer. It could offer the 2.0 behaviour, which although then
technically not JMS 1.1-compliant shouldn't actually break existing applications, or it could offer the old 1.1
behaviour, which would entail the server keeping track of the client's version as you suggest.

Do you see this as a problem? Is there a different API that would help?

Nigel




On 03/04/2012 16:02, Rob Davies wrote:
> Yikes - does this mean we need to implement different broker side behaviour - dependent on the version of JMS the client is using ?
> On 3 Apr 2012, at 15:57, Nigel Deakin wrote:
>
>> I'd like to return to this issue, which we last discussed back in August last year:
>> On 05/08/2011 15:37, Nigel Deakin wrote:
>>> I have logged this JIRA issue:
>>> http://java.net/jira/browse/JMS_SPEC-40
>> I made some detailed proposals at the time, which seemed to be acceptable to this group, though I didn't have time to take these forward and add them to the Early Draft. I've reviewed these proposals and updated them to reflect the current state of the simplified API.
>>
>> Here's the current proposal. To see a formatted version which is somewhat easier to read, please see the JIRA issue. Any further comments? Do the JMS implementers on this group see any issues with this that I may have missed?
>>
>> Description
>> ===========
>>
>> 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 (http://java.net/jira/browse/JMS_SPEC-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 (http://java.net/jira/browse/JMS_SPEC-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).
>>
>> 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.