jsr343-experts@jms-spec.java.net

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

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Thu, 29 Sep 2011 11:04:03 +0100

On 29/09/2011 08:14, Ruediger zu Dohna wrote:
> 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.

Yes, that would be consistent. But if we think *users* will ever to use ordinal() then I think this whole idea is
getting over-complicated.

>
>> (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.

Yes, that's still my proposal.

>
>> 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());
> }
>

Indeed it could. It could also be a switch statement. Personally I prefer a switch statement, as it is more explicit,
and doesn't rely on the enum order. But this is a minor issue of programming style and doesn't affect the spec. If we do
adopt the enum, I agree the order should be as you suggest.

Nigel

>> 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!
>>>>
>>>>
>>>>
>>
>>