jsr343-experts@jms-spec.java.net

[jsr343-experts] Re: Clarification on JMSContext::createConsumer

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Mon, 09 Dec 2013 15:51:47 +0000

Clebert,

On 09/12/2013 14:10, Clebert Suconic wrote:
>
>
> Message msg1 = context.createConsumer(queue1).receive(5000);
> Message msg2 = context.createConsumer(queue1).receive(5000);
>
>

I would expect this to behave in the same way as with the standard API.

Message msg1 = session.createConsumer(queue1).receive(5000);
Message msg2 = session.createConsumer(queue1).receive(5000);

(For the sake of completeness I should add that the simplified and standard APIs differ in that calling createConsumer
on a JMSContext automatically starts the connection, whereas it doesn't on a Session.)

I recorded some of the design decisions on this wiki page
https://java.net/projects/jms-spec/pages/JMS20ReasonsFAQ#Why_do_we_need_a_separate_JMSConsumer_object._Why_can_t_we_move_all_its_methods_onto_the_JMSContext?

See particularly this paragraph:

"Apart from API simplicity, a second reason for keeping a separate consumer object was to allow it to have a separate
lifecycle from the JMSContext. Some existing JMS vendors "pre-send" messages to the consuming client and cache them in
the MessageConsumer prior to delivery to the application. This means that if the consumer is closed these cached
messages can be released back to the server without closing the connection and session. Although JMS does not specify
this as a required behaviour it was thought preferable to design the simplified API in a way which would not cause
difficulties for existing implementations. For this reason, the simplified API uses a separate consumer object, the
JMSConsumer, which is very similar to the existing MessageConsumer object. "

Nigel

>
> and I just tried on my implementation and it doesn't work of course... as I create one consumer per call. Things like
> read-ahead would make it cache on the client...
>
>
> to make it always work, I would have to create a cache for createConsumer, but however, there's a complication on
> setMessageListener:
>
>
> JMSConsumer consumer1 = context.createConsumer(queue1);
> consumer1.setMessageListener(listener1);
> JMSConsumer consumer2 = context.createConsumer(queue1);
> consumer2.setMessageListener(listener2);
>
>
>
> If I make a cache, the second call would return the same consumer and hence the setMessageListener on listener2
> wouldn't work. I could of course clear my cache on the implementation once setMessageListener is used.... However
> it's a bit weird since I won't have access to close the consumer any longer.
>
>
>
> this goes related to a previous discussion on receiving messages nonymously such as:
>
>
> context.createConsumer(queue1).receive(TIMEOUT);
>
>
>
>
> Any thoughts?
>
>