users@jersey.java.net

Re: [Jersey] Enhanced Guice-Jersey integration

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 29 Jun 2009 10:58:00 +0200

On Jun 25, 2009, at 9:46 PM, Richard Wallace wrote:

> On Thu, Jun 25, 2009 at 1:40 AM, Paul Sandoz<Paul.Sandoz_at_sun.com>
> wrote:
>>
>> On Jun 24, 2009, at 2:25 AM, Richard Wallace wrote:
>>
>>> On Tue, Jun 23, 2009 at 2:14 AM, Paul Sandoz<Paul.Sandoz_at_sun.com>
>>> wrote:
>>>>
>>>> Hi Richard,
>>>>
>>>> We could modify WebApplication to have a method getProviders().
>>>>
>>>> Jersey holds information on all the injectable stuff registered
>>>> (whether
>>>> it
>>>> be Jersey or JAX-RS specific, or added by the developer). I am
>>>> wondering
>>>> if
>>>> it might be best to expose that. In fact that will be the best
>>>> way to
>>>> expose
>>>> the @*Param stuff because there is logic in the Injectable
>>>> instances to
>>>> extract stuff from the HttpContext, e.g. see the source in jersey-
>>>> server
>>>> for:
>>>>
>>>>
>>>> com
>>>> .sun
>>>> .jersey.server.impl.model.parameter.QueryParamInjectableProvider
>>>>
>>>> I wonder if we could write code to loop through the injectables
>>>> that are
>>>> registered and explicitly bind them?
>>>>
>>>> bind(c).to(cProvider).in(scope);
>>>>
>>>> At least for those within the singleton scope.
>>>>
>>>
>>> That would definitely work.
>>>
>>
>> After 1.1.1-ea i will have a look at cleaning up the internal
>> implementation
>> for expose it to the SPI.
>>
>
> Along with the OSGi changes?

Yes, but I would put this as a lower priority.


> You're a busy busy guy!

Too busy :-) your help is greatly appreciated.


> But I really
> appreciate it, thanks!
>


>>>
>>> Some of the values it returns are request-scoped, such as the
>>> request
>>> and response. I would have used some globally accessible value for
>>> UriInfo but couldn't find a way to access it. That would
>>> certainly be
>>> a far better alternative.
>>
>> I was not questioning the use of HttpContext. I think you did the
>> right
>> thing. I was wondering about how we declare what the scope is to
>> Guice.
>>
>
> By default, everything in Guice is considered "scopeless" unless you
> give it a scope. Which basically means that the Provider is consulted
> everytime you need to inject a value. For this case, I think that's
> what we want.
>

OK. That works.


>> I am quite willing to use and make changes where required to
>> GuiceyFruit
>> (with James permission, and with the view to getting such changes
>> back into
>> Guice). Is that something you are interested in? that way we might
>> be able
>> to support the constructor parameters, and get better support for
>> injection
>> of the @*Param.
>>
>> For example, see the Limitations section here;
>>
>> http://code.google.com/p/guiceyfruit/wiki/Annotations
>>
>> Currently due to the Guice restriction that @Inject must be used
>> on all
>> constructors we can only use
>> injection annotations like @Resource and @Autowired on fields and
>> methods;
>> not on constructors.
>>
>> We may try patch Guice to remove this restriction in future
>> versions of
>> GuiceyFruit
>>
>
> I saw that and that's why I pointed out it wouldn't work on
> constructor or method injection. I'd definitely be interested in
> adding support for this to GuiceyFruit and eventually getting the
> changes merged back into Guice itself. I wonder how much James has
> already looked into this and if he has any ideas.
>

Dunno.

We might be able to "plug-in" an additional binding to bind an
annotation, such as QueryParam (it does not have to be meta-annotated,
i was never sure why that was necessary expect for docs purposes), to
a provider that supports a, possibly open, set of types defined by
that provider. Then that would work consistently for all forms of
injection (the TypeListenerBinding is insufficient).

This would defer some of the responsibility of type checking to the
provider, but that checking could still be performed at module
initialization. And a helper class could be implemented to support a
fixed set of types (rather than having to register something per type).

One complication is annotations such as @QueryParam may come with
other annotations like @DefaultValue and also @Encoded (which may also
occur on the class). So there needs to be some contextual information
when injecting, namely:

1) Class/Instance where injection will occur;

2) Type of instance to be injected; and

3) Set of Annotations associated with 2).

Paul.