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: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 30 Apr 2010 17:36:20 +0200

Hi James,

You beat me to it :-)

I think we may be able to refine things as i got the following to work:

     @Path("unbound/perrequest")
     public static class InjectedPerRequestResource {

         @Context UriInfo ui;

         String x;

         @Inject
         GuiceManagedClass gmc;

         public InjectedPerRequestResource(@QueryParam("x") String x) {
             this.x = x;
         }

         @GET
         @Produces("text/plain")
         public String getIt() {
             assertEquals("unbound/perrequest", ui.getPath());
             assertEquals("x", x);

             return gmc.toString();
         }
     }

Thus we can also support the case when Jersey instantiates and Guice
injects too i.e. when there are constructors with no @Inject with
@Injected fields/methods.

I will merge things.

Paul.

On Apr 30, 2010, at 5:28 PM, James Strachan wrote:

> 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/
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>