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 15:56:42 +0100

On 30 April 2010 15:48, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>
> On Apr 30, 2010, at 4:07 PM, James Strachan wrote:
>
> I started tinkering with some Guice IoC in a Scalate Jog project...
> http://scalate.fusesource.org/documentation/jog.html
>
> and was quite suprised to not have a resource injected when using
> Guice's @Inject. Turns out I think that the code only attempts to use
> Guice to inject if it can see an @Inject annotation on a constructor -
> or the resource is bound with the module.
>
>
> Yes.
>
> I just wondered why this was done?
>
> It simply did not occur to me to check for other uses of @Inject. I was just
> looking for an explicit marker to ensure Guice support would not gobble up
> all classes to be instantiated by Guice (see later).
>
> I figured at least check for
> method/field annotations too? I've raised an issue to track it...
> https://jersey.dev.java.net/issues/show_bug.cgi?id=520
>
> Maybe we should just change the
> GuiceComponentProviderFactory.isImplicitGuiceComponent method to
> check for @Inject on any field or method too?
>
>
> Yes, i think we can modify to do more checking. Basically if it quacks like
> a Guice component but is not bound let Guice instantiate it.
>
> Would it be too bad to just assume Guice is gonna create an instance I
> wonder?
>
> The problem is that thorny issue of constructor injection:
> public class MyClass {
>    public MyClass(@PathParam("p") String p) {
>      ...
>    }
> }
> thus we don't want Guice to instantiate stuff like the above.
> Perhaps we can try these rules:
> 1) check if there is a constructor annotated with @Inject, if not
> 2) check for fields/methods annotated with @Inject.
> and let Guice throw up errors if construction fails?
> 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 *really* do want to sort out these DI issue for Jersey 2.x. Namely ripping
> out the guts of Jersey re-using a proper DI framework. Re: discussons on
> using Weld. As i have said before I would really like to use a fork of Guice
> + modifications (with appropriate integration to CDI and Spring). But i sort
> of feel stuck, forking Guice obviously has issues but as long as it is
> backwards compatible with Guice then maybe developers will not mind?
> BTW on request i modified the Guice dependency to point the maven central
> repo rather than GuiceyFruit but still give the latter a plug in the
> dependency docs.
> https://jersey.dev.java.net/nonav/documentation/1.2-SNAPSHOT/user-guide.html#d4e1669

No worries :)

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