dev@jsr311.java.net

Re: JSR311: Targets for _at_*Param, _at_DefaultValue, _at_Encoded

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Thu, 20 Mar 2008 08:21:16 -0700

On Mar 20, 2008, at 6:42 AM, Stephan Koops wrote:
>
> Before discussing more:
> Do you (and all) agree, that the specification should primarily
> support the default lifecycle (instantiation per request), but make
> other lifecycles possible?

That is my preference.

>
> Perhaps you discussed this earlier, but I do not read this, because
> I entered the discussion late?
>
> clarify missunderstanding (solution proposal later)
>> The use of: String s =
>> tlCharSequence.get().toString(); is really convoluted and
>> ugly.
> I think here is a misunderstanding. My proposals mean:
>
> @*Param(...) private CharSequence charSequence;
>
> Default lifecycle runtime environments inject a String, singelton
> runtimes inject a proxy CharSequence, which will return the String
> by toString().

Sorry, I still think this is awkward.

> The other possibility:
>
> @*Param(...) private ThreadLocal<String> name;
>
> it is read by
>
> name.get();
>
I think its simpler to just say that for anything other than per-
request lifecycle, use method parameters and leave it at that. This
doesn't seem like a huge restriction to me. Having lots of complex
rules about what types you can use for fields depending on what
lifecycle you use is too much IMO - YAGNI.

>> and i would prefer to specify some very simple and concise rules:
>> for non-per-request life-cycle a root resource class must have all
>> of the following:
>>
>> 1) A constructor with no per-request-based annotations
>> (we already require this rule)
> Sorry, this rule is not specified. The spec define: "A public
> constructor MAY include parameters annotated with one of the
> following: @Context, @HeaderParam, @CookieParam, @MatrixParam,
> @QueryParam or @PathParam" (chapter "Resources", section "Resource
> Classes", subsection "Constructor")

It also says: "However, depending on the resource class lifecycle and
concurrency, per-request information may not make sense in a
constructor."

An implementation may not be able to determine the lifecycle of a
resource class if the impl defers object creation to an IoC framework.
Therefore I don't think we can forbid per-request @*Param on ctor
params. All we can do IMO is warn developers that they might not make
sense - same for fields.

Marc.

>>
>> Stephan Koops wrote:
>>> Hello,
>>>
>>> a new (a little bit extended looking) proposal:
>>>
>>> (preambel :-) )
>>> The default lifecycle for root resource classes (abbr: rrcs) is,
>>> that an instance is created for every request. And for the default
>>> lifecycle the specification should be made, IMO, but allow other
>>> lifecycles. If an implementation use another lifecycle, it has to
>>> accept more work in a little number of cases, IMO.
>>>
>>> To support this: For rrcs we have the following cases (did I miss
>>> something?):
>>>
>>> 1. no fields and @*Param annotated bean setters are available -
>>> > no
>>> problem.
>>> 2. all fields and bean setters have type ThreadLocal<Whatever> -
>>> > no
>>> problem.
>>> 3. at least one not ThreadLocal typed and @*Param annotated
>>> field:
>>> can work, if the runtime could support a ThreadLocal
>>> implementation for the given type (e.g. proxy subclass).
>>> 4. at least one @*Param annotated bean setters have not type
>>> ThreadLocal<Whatever>: can work (setter use ThreadLocal), but
>>> runtime don't know.
>>> 5. other, non @*Param-annotated, non @Context and non ThreadLocal
>>> fields are be available -> will typically not work, because
>>> it is
>>> used as normal instance variable.
>>>
>>> A bettering for case 3: We could also allow CharSequence with
>>> String as default for fields and bean setter, so a String like
>>> type is also available for runtime environments with singelton rrc
>>> lifecycle. I think, that Strings (or more general CharSequences)
>>> are mostly used for @*Param values. Perhaps we could also allow
>>> java.lang.Number with Double as default, if a "." is available in
>>> the String to parse, or Integer or Long, if no "." is available in
>>> the String to parse. An implementation could also create a
>>> subclass thread local proxy.
>>>
>>> A solution for the last case could be an official annotation
>>> @SingeltonReady on a rrc. If it is available on a rrc, also a non-
>>> default lifecycle could be supported, also if checks 3 and 4 do
>>> not pass.
>>>
>>> This concept looks complicated, but it has the following advantages:
>>>
>>> * nothing will change for implementations and app developers
>>> using
>>> default rrc lifecycle (only add the injection in annotated
>>> fields
>>> an bean setters), but
>>> * a lot of flexibility for @*Param (everywhere (iv)/(v) on
>>> rrcs and
>>> also on other resource classes)
>>> * singelton lifecycle with detection of trouble creating rrcs is
>>> available, but also
>>> * allow rrcs to be runned as singelton, also if it's interface
>>> does
>>> not show this. (e.g. setter with int parameter, but rrc maps
>>> this)
>>>
>>> The additional work for singelton lifecycle runtime environments
>>> is to check, if the rrc is valid for this lifecycle (see 4 points
>>> at top).
>>>
>>> What do you think?
>>>
>>> Stephan
>>>
>>> Marc Hadley schrieb:
>>>> On Mar 19, 2008, at 5:09 AM, Paul Sandoz wrote:
>>>>> Option (v) seems a no go to me since AFAICT it is not possible
>>>>> to cleanly and directly proxy non-interface based stuff, thus
>>>>> String is not possible since it is final, makes it hard to
>>>>> support things extending Number (Integer, BigDecimal etc), and
>>>>> there is no easy solution for user-defined classes to process
>>>>> parameters. Hence one would have to explicitly declare:
>>>>>
>>>>> @QueryParam("abc") ThreadLocal<String> abc;
>>>>>
>>>>> which sucks IMO.
>>>>>
>>>> Agreed, given this new information I think option (v) is a no-go.
>>>>
>>>>> If we really have to allow @*Param on fields and methods then
>>>>> option (iv) seems better. It introduces an additional dependency
>>>>> on life-cycle. In effect it is not just a Singleton resource,
>>>>> but anything other than a per-request resource where an instance
>>>>> of the resource class is retained beyond the scope of a request.
>>>>> (There is an existing dependency on constructors).
>>>>>
>>>>> I would be inclined to say field and method (bean setter) are
>>>>> only supported for per-request resources. Thus if a developer
>>>>> chooses a non-per-request resource there are less ways for
>>>>> bullets to hit feet.
>>>>>
>>>> Seems like (iv) is closest to what the majority of the EG
>>>> preferred so unless there's further discussion I think that is
>>>> the option we should go for.
>>>>
>>>> Marc.
>>>>> Marc Hadley wrote:
>>>>>> There's been a lot of discussion of whether or not to expand
>>>>>> the targets (i.e. what Java artifacts you can use the
>>>>>> annotation on) of the @*Param annotations (i.e. @PathParam etc
>>>>>> al). If we do add targets for these annotations I think we also
>>>>>> need to do the same for @DefaultValue and @Encoded. I'm
>>>>>> uncomfortable adding targets that are only supported in some
>>>>>> implementations so if we do add targets they will be required
>>>>>> to be supported on resource classes (not providers) in all
>>>>>> implementations.
>>>>>> Discussion so far has been between Bill, Stephan and myself,
>>>>>> I'd like to hear from others hence this poll. Please choose
>>>>>> from the following and reply to the list with your selection.
>>>>>> Silence means you don't care what happens - how could that
>>>>>> be ;-).
>>>>>> Here are the options for target I see:
>>>>>> (i) Parameter. The status quo. Works with any lifecycle.
>>>>>> (ii) Parameter and field. Spec will warn that use on a field in
>>>>>> a singleton resource isn't supported.
>>>>>> (iii) Parameter and field. Spec will require use of a proxy for
>>>>>> field injection. Pro: singletons can be supported. Con: will
>>>>>> affect performance. Con: still won't work for simple types,
>>>>>> spec will warn about this.
>>>>>> (iv) Parameter, field and method (bean setter). Spec will warn
>>>>>> that use on a field in a singleton resource isn't supported and
>>>>>> that use on method will require application-managed thread-
>>>>>> local handling. Pro: bean setter enable support for singletons.
>>>>>> Con: complicated bean setters.
>>>>>> (v) Parameter, field and method (bean setter). Spec will
>>>>>> require use of a proxy for field and method injection. Same
>>>>>> pros and cons as (iii).

---
Marc Hadley <marc.hadley at sun.com>
CTO Office, Sun Microsystems.