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).
>>> Vote early, vote once.
>>> Marc.