jsr343-experts@jms-spec.java.net

[jsr343-experts] Re: (JMS_SPEC-45) Clarify and improve Connection.createSession

From: Ruediger zu Dohna <ruediger.dohna_at_1und1.de>
Date: Thu, 29 Sep 2011 09:14:46 +0200

Nigel,

On 28.09.2011 18:14, Nigel Deakin wrote:
> May I try to summarise what I think is being proposed here?
>
> 1. We define a new enum javax.jms.SessionType
>
> public enum SessionType { AUTO_ACKNOWLEDGXE, CLIENT_ACKNOWLEDGE,
> DUPS_OK_ACKNOWLEDGE, SESSION_TRANSACTED }

I'd prefer to put SESSION_TRANSACED first, so the enum ordinals match
the constant values in Session.

> (Note, I'm deliberately not calling this an acknowledgement type since
> local transacted sessions are for sending messages as well)

You are right, I hadn't been thinking about this before! The JMS 1.1
standard had the potential to distinguish the transaction behavior for
sending and receiving; but it didn't leverage it, as it assumed that if
you want to both send and receive messages in one session, both will be
transacted or neither... which is technically very feasible but there
might be use cases that require client acknowledged receives and
transaced sends. Even so, if you only want to untransactionally send
messages, it would be strange to create a Session with some _ACKNOWLEDGE
SessionType, wouldn't it? Renaming e.g. AUTO_ACKNOWLEDGE to
SESSION_UNTRANSACTED or something wouldn't be quite right, either? What
do you think?

> 2. We add a new method to the interface javax.jms.Connection:
>
> Session createSession(SessionType sessionType) throws JMSException;
>
> 3. Applications could create a Session using
>
> connection.createSession(SessionType.CLIENT_ACKNOWLEDGE);

That other method without any arguments would be very useful as well.

> 4. Implementations could implement the new method however they like, but
> they could do using something like:
>
> @Override
> public Session createSession(SessionType sessionType) throws JMSException {
>
> if (sessionType==SessionType.AUTO_ACKNOWLEDGE){
> return createSession(false,Session.AUTO_ACKNOWLEDGE);
> } else if (sessionType==SessionType.CLIENT_ACKNOWLEDGE){
> return createSession(false,Session.CLIENT_ACKNOWLEDGE);
> } else if (sessionType==SessionType.DUPS_OK_ACKNOWLEDGE){
> return createSession(false,Session.DUPS_OK_ACKNOWLEDGE);
> } else if (sessionType==SessionType.SESSION_TRANSACTED){
> return createSession(true,Session.SESSION_TRANSACTED);
> }
> throw new JMSException("Invalid sessionType");
>
> }

If we reordered the enum, it could simply be:

@Override
public Session createSession(SessionType sessionType) {
   boolean transaced = (sessionType == SessionType.SESSION_TRANSACTED);
   return createSession(transacted, sessionType.ordinal());
}

> 5. Client applications would look something like:
>
> Session session = connection.createSession(SessionType.CLIENT_ACKNOWLEDGE);
>
> Do we need anything apart from that?
>
> (Note that I think we're still undecided about whether we want to define
> these enums, but that doesn't stop us working on what they might look like)
>
> Nigel
>
> On 27/09/2011 07:54, Rüdiger zu Dohna wrote:
>> John,
>>
>> the constants are:
>> public static final int AUTO_ACKNOWLEDGE = 1;
>> public static final int CLIENT_ACKNOWLEDGE = 2;
>> public static final int DUPS_OK_ACKNOWLEDGE = 3;
>> public static final int SESSION_TRANSACTED = 0;
>>
>> So it would match the enum:
>>
>> public AcknowledgeType {
>> SESSION_TRANSACTED, AUTO_ACKNOWLEDGE, CLIENT_ACKNOWLEDGE,
>> DUPS_OK_ACKNOWLEDGE;
>> }
>>
>> I understand, though, that ordinals should generally not be used to
>> transport semantics (cf. Effective Java, Item 31),
>> but as this use is deprecated _and_ was stable for 9 years, I'd say we
>> are safe to ignore that warning ;)
>>
>>
>> Rüdiger
>>
>> On 27.09.2011 01:58, John D. Ament wrote:
>>> Rudiger,
>>>
>>> Perhaps, though not guaranteed. I would presume that each value in the
>>> enum set would have a numeric value matching the ordinal as defined in
>>> Session.
>>>
>>> John
>>>
>>> On Mon, Sep 26, 2011 at 10:30 AM, Rüdiger zu Dohna
>>> <ruediger.dohna_at_1und1.de <mailto:ruediger.dohna_at_1und1.de>> wrote:
>>>
>>> John,
>>>
>>> the valueOf(int) method is a synonym for values()[i], isn't it?
>>>
>>> And should we really declare this method:
>>> > Connection.createSession(__boolean,EnumClassName);
>>>
>>> The "transacted" boolean is redundant to the EnumValue
>>> SESSION_TRANSACTED, isn't it?
>>>
>>>
>>> Rüdiger
>>>
>>>
>>> On 26.09.2011 11 <tel:26.09.2011%2011>:44, John D. Ament wrote:
>>>
>>> Thanks Rudiger for pushing this. I was trying to avoid "force" but
>>> figure I should pitch in; here's my attempt at clarifying my
>>> request,
>>> hopefully I don't mess it up :-)
>>>
>>> The way I see it, for backwards compatibility, we leave the int
>>> method
>>> in place:
>>>
>>> Connection.createSession(__boolean,int);
>>>
>>> In the enum we introduce a valueOf method, taking the int value
>>> as an
>>> argument and returning the enum. We then add the following
>>> methods, and
>>> mark the current int method as deprecated:
>>>
>>> Connection.createSession(__boolean,EnumClassName);
>>> Connection.createSession(); //for use in EE
>>> Connection.createSession(__EnumClassName);
>>>
>>> We're not introducing four enums, we're introducing one enum
>>> that has 4
>>> values within it. The valueOf method helps us bridge the old
>>> way for
>>> calling and the new one. Here's how I figure each method
>>> would be used:
>>>
>>> Connection.createSession(__boolean,int);
>>> just returns createSession(boolean, EnumClassName.valueOf(int));
>>>
>>> Connection.createSession();
>>> Just creates a default transacted session for EE use, with
>>> behavior in
>>> EE and SE as defined by Nigel below.
>>>
>>> Connection.createSession(__EnumClassName);
>>> Transactional state as noted by Nigel above.
>>>
>>> Connection.createSession(__boolean,EnumClassName);
>>> Same behavior as today.
>>>
>>> John
>>>
>>>
>>> On Mon, Sep 26, 2011 at 2:55 AM, Rüdiger zu Dohna
>>> <ruediger.dohna_at_1und1.de <mailto:ruediger.dohna_at_1und1.de>
>>> <mailto:ruediger.dohna_at_1und1.__de
>>> <mailto:ruediger.dohna_at_1und1.de>>> wrote:
>>>
>>> On 23.09.2011 16:34, Nigel Deakin wrote:
>>>
>>> ...further new method ... Session createSession()
>>> Any comments?
>>>
>>>
>>> Exquisit simplification... +1
>>>
>>>
>>> Separately, John suggested:
>>>
>>> Could your spec change perhaps use an enum to
>>> describe the
>>> sessionMode as well?
>>>
>>>
>>> If this has been a new API then an enum would have
>>> definitely
>>> been the right thing, and my initial reaction was to agree
>>> with John's proposal. However another EG member has
>>> pointed out
>>> that since we already have four static constants
>>> (Session.AUTO_ACKNOWLEDGE etc) adding four enum values which
>>> would effectively duplicate these would unnecessarily
>>> complicate the API. I'm therefore inclined to stick
>>> with the
>>> existing four static constants. Does anyone else have any
>>> particular views on this?
>>>
>>>
>>> I'd prefer the enum, too. The old constants could be marked as
>>> deprecated and eventually removed. All other methods that
>>> take such
>>> an int, would have to be marked as deprecated as well and
>>> get a new
>>> variant with the enum. I'm all for cleaning up APIs!
>>>
>>>
>>>
>
>