users@jersey.java.net

Re: [Jersey] Enhanced Guice-Jersey integration

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 25 Jun 2009 10:40:54 +0200

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.


>>
>> It is a shame we cannot use the Matchers.any() for bind:
>>
>>
>> bind
>> (Matchers
>> .any
>> ()).annotatedWith
>> (QueryParam.class).to(qProvider).in(RequestScoped.class)
>>
>> ?
>
> No, the other problem with that, AFAIK, is that the annotations you
> bind with have to be annotated with the Guice BindingAnnotation.
>

Ah, yes.


>>
>> I cannot recall if James got this to work with GuiceyFruit. (Also
>> not that
>> the Guice/Jersey integration supports injection onto fields of
>> Guice-managed
>> classes).
>>
>>
>> The following:
>>
>> @Provides public UriInfo uriInfo(HttpContext httpContext) {
>> return httpContext.getUriInfo();
>> }
>>
>> returns a request-scoped value, the httpContext is thread local but
>> the
>> values it returns are not. Is that an issue?
>>
>
> 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.


>
>
>> Jersey registers thread local proxies for UriInfo etc to be
>> injected onto
>> singletons and the actual instances to be injected on per-request
>> resources.
>> It tries to optimize as much as possible to avoid the repeated use
>> of thread
>> locals when the request is available directly.
>>
>
> That's the advantage of being directly wired into the request
> processing lifecycle. With a proper hook we could create a child
> injector to be used for that request, and that would avoid any of the
> thread local stuff. But that's the only way I can think of. Even
> using the Guice servlet integration and putting that stuff in the
> RequestScope would mean storing it in the ServletRequest attributes.
> But the ServletRequest itself is accessed via a thread local. So, no
> matter what you have to have at least a single thread local.

OK. I guess there is no way of saying: "this thing is compatible with
the @RequestScope, but you do not need to manage it".


> I'm not
> sure if that or creating a child injector would be more performant.
> Probably depends on the number of objects that are going to be created
> in a single request that will be injected with request data.
>

OK. I guess we should get things functional first and worry about
performance later.

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

Paul.