users@jersey.java.net

Re: [Jersey] Using Guice with JAX-RS

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 07 Oct 2008 17:03:02 +0200

On Oct 7, 2008, at 3:56 PM, Gili wrote:
>
>
> Paul Sandoz wrote:
>>
>> You should not have to check for the PerRequest annotation. It should
>> be sufficient to use the "scope" that Jersey is requesting. It seems
>> to me there are some cases that may be reliably consistent to check:
>>
>
> Checking the "scope" that Jersey is requesting is not enough,
> because I want
> to be able to differentiate between the default scope versus someone
> explicitly asking for PerRequest. I could implement a
> ResourceProvider to do
> this but I found this approach easier.

Something is not quite right, it is breaking layering...


> I want to prevent users from using both Jersey and Guice scopes on
> the same
> field.

Class?


> This means that a default scope (which just happens to be PerRequest)
> with a Guice scope is okay, but @PerRequest with a Guice scope is not.
>

What if there is a class is annotated with
@com.google.inject.Singleton and not annotated with @PerRequest? then
there will be a conflict with what Guice provides and what Jersey
expects. For example, given the following:

   @Path("xyz")
   @com.google.inject.Singleton
   public class XYZ {
     @Context UriInfo ui;
   }

Jersey will think an instance returned by the component provider is a
new instance and thus inject a direct instance of UriInfo that is
associated with the current request onto XYZ. Any concurrent or
subsequent requests to XYZ will result in odd behavour when accessing
state of "ui" because they will be accessing URI information of the
firs request that resulting in instantiation of XYZ.

I think we need not worry about 3rd party Guice scopes for the moment
and instead concentrate on the known scopes supplied by Guice and we
need to validate the Jersey scope against the Guice scope and
explicitly check, for example:

   if (scope == Scope.PerRequest) {
     if (<there is a Guice-based scope annotation on the class that is
not @RequestScoped>) {
        // CONFLICT
      }
   } else if (scope == Scope.Singleton) {
     if (<there no Guice-based scope annotation @Singleton>) {
       // CONFLICT
      }
   } else if (scope == Scope.Undefined) {
     ...
   }

That way we ensure that what Jersey expects in sync with what Guice
produces. This is essentially what the Spring component provider does.
It should work under the following scenarios:

   @Path("xyz")
   public class XYZ {
     @Context UriInfo ui;
   }

   @Path("xyz")
   @com.google.inject.servlet.RequestScoped
   public class XYZ {
     @Context UriInfo ui;
   }

   @Path("xyz")
   @PerRequest
   public class XYZ {
     @Context UriInfo ui;
   }

   @Path("xyz")
   @com.google.inject.servlet.RequestScoped
   @PerRequest
   public class XYZ {
     @Context UriInfo ui;
   }

   @Path("xyz")
   @com.google.inject.Singleton
   @Singleton
   public class XYZ {
     @Context UriInfo ui;
   }

Then we could have a default Guice meta-resource provider that maps
things similar to the SpringResourceProvider so we do not require the
Jersey-based resource provider annotations.


>
> Paul Sandoz wrote:
>>
>> It is frustrating that one cannot tell Guice which constructor to use
>> with a list of constructor parameters, where null values mean Guice
>> should determine the parameters.
>>
>
> Guice expects you to mark up one of your constructors with @Inject at
> compile-time. This is your way of telling it which constructor to
> use. I
> think what is missing is not so much telling Guice which constructor
> to use
> but being able to merge the Jersey and Guice injection
> configuration. For
> example, Jersey knows how to inject X but Guice knows how to inject Y.

Yes. Note that JAX-RS has a rule for choosing the appropriate
constructor of a class, which is why Jersey wants to be in control.
But i do not see why this could not be overridden by an IoC framework.


> It
> would be nice to be able to import Jersey's configuration into Guice
> once at
> startup and just use Guice from that point onward.
>

Yes, i was wondering what the likes of Spring, Guice and WebBeans have
in terms of that.

Paul.