users@jersey.java.net

Re: Get rid of requirement for no-arg constructor

From: Richard Wallace <rwallace_at_thewallacepack.net>
Date: Mon, 26 Nov 2007 19:44:54 -0800

Paul Sandoz wrote:
> Richard Wallace wrote:
>> Hello,
>>
>> I'm trying to get Guice working with Jersey and am running into one
>> roadblock. The thing is that I really like to use constructor
>> injection whenever possible. I want to do this with my resources.
>> To that effect I've changed the GuiceProvider.getInstance() method
>> from Christians blog post to
>>
>> public Object getInstance(ResourceProviderContext context)
>> throws ContainerException {
>> Object resource =
>> getInjector(context).getInstance(resourceClass);
>> context.injectDependencies(resource);
>> return resource;
>> }
>>
>> That way Guice is completely responsible for creating and injecting
>> dependencies into the resource object without the need for a no-arg
>> constructor.
>>
>
> It would be nice to 'mix-in' Jersey specific constructor parameter
> injection with Guice constructor parameter injection. You can get the
> Jersey specific per-request parameters using:
>
> ResourceProviderContext.getParameterValues
>
> But Marc could not find a way in Spring to do the merging, perhaps in
> Guice it is possible?
>
I agree this would be nice. I think I know a way to do it with Guice,
but it's a bit hacky. With Guice you can bind to a given class with a
certain annotation either a class that Guice will instantiate, an
instance that Guice should use, or a an instance of a Guice Provider.
It's this last one that we could use, but the question becomes how does
the Guice Provider get the information for the request because this
binding happens at startup. The best solution that I've been able to
come up with is to stuff the Jersey objects that could be injected into
a ThreadLocal that the Guice Provider will use to get the objects and
return them to Guice for injection. But I'm not sure about what all the
objects are that could be injected or the best way to get access to
them. I guess I could just use the
ResourceProviderContext.getParameterValues and only stuff those into the
ThreadLocal for the Guice Provider to use.
>
>> This should work. But I'm running into a problem because Jersey is
>> building an AbstractResource internally to track information about
>> the resource class. This wouldn't be a problem except that one of
>> the things that it is trying to find is a no-arg constructor. Why
>> does it do that? I've search for references to the getConstructor()
>> method and usages of the AbstractResourceConstructor class, but they
>> are only used within AbstractResource and it doesn't actually do
>> anything with the information, it seems to get it just to have it.
>>
>> Would it be possible to eliminate this completely and get rid of the
>> no-arg constructor requirement?
>>
>
> Great to see you getting deep into the code :-)
>
> As i understand this is a temporary issue. Jakub is working on an
> abstract resource model, so that we can use meta-data other than
> annotations and hide the validation of a resource from things that the
> model (e.g. the runtime or for WADL generation), so he can provide
> more accurate information on this aspect.
>
> My understanding is that although some exceptions are printed out it
> should not affect the working of resource providers. Is that the case
> for you?
>
Oh, you're right. I wonder what was going on. Anyways, looking at the
code in trunk this is no longer a problem at all.
> Paul.
>

Thanks,
Rich