jsr339-experts@jax-rs-spec.java.net

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Re: Back To DI in Subresources

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Fri, 27 Apr 2012 13:00:11 +0100

Hi Marek

On 27/04/12 12:27, Marek Potociar wrote:
>
> On Apr 20, 2012, at 10:47 PM, Sergey Beryozkin wrote:
>
>> On 20/04/12 19:34, Marek Potociar wrote:
>>>
>>> On Apr 19, 2012, at 11:01 AM, Sergey Beryozkin wrote:
>>>
>>>> On 17/04/12 16:37, Santiago Pericas-Geertsen wrote:
>>>>>
>>>>> On Apr 17, 2012, at 7:45 AM, Marek Potociar wrote:
>>>>>
>>>>>> There are 2 solutions that I've been thinking about:
>>>>>>
>>>>>> 1. introduce an injectable request-scoped ResourceContext with
>>>>>> methods like inject(Class<?> subresourceClass), inject(Object
>>>>>> subresource)
>>>>>> 2. update the spec to mandate field injection on the sub-resource
>>>>>> instances returned by sub-resource locator.
>>>>>>
>>>>>>
>>>>>> So far I am leaning towards #1 as it seems more flexible.
>>>>>>
>>>>>> Any thoughts on the above?
>>>>>
>>>>> Why not both? As you say, (1) is more flexible but (2) is quite
>>>>> convenient.
>>>>>
>>>>
>>>> I don't understand how the sub-resource injection can work at all.
>>>> Lets take an example where a root resource is a singleton.
>>>>
>>>> This root resource can return sub-resource instances. Such instances
>>>> can be created at a per-request basis or may've been pre-allocated
>>>> and are singletons too. Only the root resource knows the rules.
>>>
>>> Again, that's why I am leaning towards #1 as it is more flexible and
>>> lets the parent resource decide whether or not the injection should
>>> be used and how.
>>>>
>>>> How can the runtime make sure that the injection into sub-resources
>>>> is thread-safe ?
>>>
>>> It should not. It should be the responsibility of the parent resource.
>>
>> OK. I may've mis-read the original proposal, sorry if I am.
>>
>> What sort of DI is being discussed here ?
>> I'm saying that something like
>>
>> public RootResource {
>> private SubResource mySubResource;
>> @Path
>> public SubResource getSubResource() {
>> return mySubResource;
>> }
>> }
>>
>> public SubResource {
>> @Context
>> private UriInfo ui;
>> @GET @Produces("text/plain")
>> public String getTest() {
>> return "subresource";
>> }
>> }
>>
>> specifically the injection of UriInfo into SubResource is difficult
>> for the runtime to support because it is not aware of SubResource's
>> lifecycle.
>> You are saying the injection is the responsibility of the parent
>> resource (RootResource), so we can expect SubResource have a UriInfo
>> setter for example. I agree, this is what the spec says now.
>>
>> So, what DI support is actually being discussed in this thread ?
>> Can you please type some code ?
>
> What I have in mind is something like:
>
> @Path("root")
> public class RootResource {
> @Context ResourceContext ctx;
>
> @Path("sub1")
> public SubResource getSubResource() {
> return ctx.inject(SubResource.class); // instantiate & inject
> }
>
> @Path("sub2")
> public SubResource getSubResource() {
> SubResource sr = ... obtain the custom-managed instance somehow ...
> return ctx.inject(sr); // inject the instance
> }
> }
>
> public class SubResource {
> @QueryParam("q") private String query;
> @Context private UriInfo uriInfo;
> ...
> }
>
> In "sub1" case the root resource should be able to ask JAX-RS runtime to
> provide a new injected sub-resource instance. In "sub2" case the
> resource should be able to retrieve the sub-resource instance in a
> custom way, but if it decides that it still wants to inject the
> instance, it should be able to do so. Makes sense?

Thanks for this example.
I'm sorry but IMHO the "ctx.inject(SubResource.class);" looks very
anti-JAXRS to me.

The application code does not need to be *explicitly* concerned about
delegating to the injected contexts for the instantiation & injection of
the sub-resource handlers. It kind of mixes the runtime (the
*transparent* injection of contexts) and the application concerns.

We've a discussion on the CXF list with Jakub Bochenski. He actually
also listed the above option but we both agreed that it was not ideal, a
bit intrusive, etc.

Jakub proposed another option, having a concrete no-op or abstract
'look-up' method similar to what is supported in Spring, example,

abstract SubResource getSubresource();

which the root resource would call.

That seems like a cleaner option for cases where it os really important
to get subresources having the internal contexts magically injected.

Btw, what is the real use case for sub-resources having the contexts
injected. In the case of root resources it is needed because the root
resources can't get them from anywhere else. In case of sub-resources,
why it is deemed problematic to have say 'setUriInfo(UriInfo)' added to
such a sub-resource ?

Thanks, Sergey



>
> Marek
>>
>> Cheers, Sergey
>>>
>>> Marek
>>>
>>>>
>>>> Thanks, Sergey
>>>>> -- Santiago
>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I would like to re-activate the already mentioned issue of lack of
>>>>>>> support of DI in sub-resources.
>>>>>>>
>>>>>>> Usually you are going to separate JAX-RS resources and services into
>>>>>>> separate classes. In that case services are going to be injected into
>>>>>>> resource with @Inject (it works already fine in Java EE 6).
>>>>>>>
>>>>>>> However: usually JAX-RS runtime is navigating from the main Resource
>>>>>>> to the sub-resource class via the @Path annotation.
>>>>>>>
>>>>>>> As developer you are creating a sub-resource using an ordinary "new"
>>>>>>> and a constructor with parameters. The sub-resources instance is no
>>>>>>> more managed and injection is not available.
>>>>>>>
>>>>>>> Proposal: we need a way to pass an instance to a JAX-RS runtime to
>>>>>>> inject dependencies.
>>>>>>>
>>>>>>> Btw. parameterless constructors are not enough - usually you are
>>>>>>> going to pass some context from the main resource to the sub
>>>>>>> resources.
>>>>>>>
>>>>>>> See also: https://java.net/jira/browse/JAX_RS_SPEC-72
>>>>>>>
>>>>>>> thanks,
>>>>>>>
>>>>>>> adam
>>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Sergey Beryozkin
>>>>
>>>> Talend Community Coders
>>>> http://coders.talend.com/
>>>>
>>>> Blog: http://sberyozkin.blogspot.com
>>>
>>
>>
>> --
>> Sergey Beryozkin
>>
>> Talend Community Coders
>> http://coders.talend.com/
>>
>> Blog: http://sberyozkin.blogspot.com
>


-- 
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com