users@jersey.java.net

Re: [Jersey] Guice injection does not support field/method injection without forcing you to bind the Resource class to the module...

From: James Strachan <james.strachan_at_gmail.com>
Date: Fri, 30 Apr 2010 16:28:23 +0100

On 30 April 2010 16:14, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>
> On Apr 30, 2010, at 5:06 PM, James Strachan wrote:
>
>> On 30 April 2010 15:56, James Strachan <james.strachan_at_gmail.com> wrote:
>>>
>>> On 30 April 2010 15:48, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>>>>
>>>> Do you know if it is possible to pass an instance to Guice to be
>>>> injected
>>>> on? If so we might be able to support Jersey constructing + injecting,
>>>> then
>>>> Guice injecting.
>>>
>>> Yes.
>>>
>>> injector.injectMembers(object)
>>>
>>>
>>> http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Injector.html#injectMembers(java.lang.Object)
>>>
>>> I've just hacked up a test case to try use this method - but have been
>>> getting some strange failures. (You might be able to figure this out
>>> quicker than I can).
>>>
>>> So I think the current behaviour of looking for a constructor with
>>> @Inject is correct; its just we also need to use
>>> injector.injectMembers(object) on objects which Jersey creates.
>>> Haven't tested yet if that call fails if there's no @Inject
>>> annotation; I suspect not.
>>
>> I get this error when I try do that...
>>
>> java.lang.RuntimeException: The scope of the component class
>> com.sun.jersey.server.impl.container.servlet.JSPTemplateProcessor must
>> be a singleton
>>       at
>> com.sun.jersey.core.spi.component.ioc.IoCProviderFactory.wrap(IoCProviderFactory.java:99)
>>       at
>> com.sun.jersey.core.spi.component.ioc.IoCProviderFactory._getComponentProvider(IoCProviderFactory.java:90)
>>       at
>> com.sun.jersey.core.spi.component.ProviderFactory.getComponentProvider(ProviderFactory.java:150)
>>       at
>> com.sun.jersey.core.spi.component.ProviderFactory.getComponentProvider(ProviderFactory.java:128)
>>       at
>> com.sun.jersey.core.spi.component.ProviderServices.getComponent(ProviderServices.java:232)
>>       at
>> com.sun.jersey.core.spi.component.ProviderServices.getProvidersAndServices(ProviderServices.java:149)
>>       at
>> com.sun.jersey.server.impl.template.TemplateFactory.<init>(TemplateFactory.java:60)
>>       at
>> com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:804)
>>       at
>> com.sun.jersey.guice.spi.container.servlet.GuiceContainer.initiate(GuiceContainer.java:112)
>>
>>
>> Just hacking the code to only try call injector.injectMembers if the
>> type has field/method injection with @Inject...
>>
>
> Odd, can you send a diff of changes?

Whoops! I'd just commit a fix before getting this email, sorry! Its a
fairly minor fix so should be easy to roll back if you like. Here's a
quick description...

* I added a new test case to GuiceUnBoundTest.java (feel free to move
it to another test if you like).

* I moved the code in GuiceComponentProviderFactory that determines
Guice scope via BindingScopingVisitor to a new private function (as I
needed to call it too from a different point in the
getComponentProvider method), so there's a new
getComponentScope(Key<?> key, Injector i) method

* if there's no @Inject constructor but there is an @Inject field or
method, we now create GuiceManagedComponentProvider rather than return
null

* the GuiceManagedComponentProvider now uses injector.injectMembers(object)

This last bit could be changed - maybe to use a different Provider
implementation if you like instead of GuiceManagedComponentProvider? I
wasn't sure if GuiceManagedComponentProvider might be intended for
something else?

-- 
James
-------
http://macstrac.blogspot.com/
Open Source Integration
http://fusesource.com/