users@jersey.java.net

Re: [Jersey] Appeal to jersey developers for better+reliable javax.inject/cdi/weld support

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 22 Apr 2010 23:44:32 +0200

On Apr 22, 2010, at 11:01 PM, Morten wrote:
> Yes, the only source I have now for this info is the mailing list +
> my own experiments.
>
>> Only CDI magic :-) Jersey needs to register a CDI extension
>> so that it can adapt the injection targets and inject at the
>> right point in the CDI managed life-cycle. The problem is
>> that CDI magic gets invoked before Jersey is properly
>> started (before the Jersey servlet is initialized) thus it
>> needs to cache the processor injection target events.
>
> Yea, complicated..... I had a similar but simpler situation where I
> needed my Junit tests to be CDI injected and I just called into
> beanmananger to inject into the instance at setup of the test. Of
> cause this means that the test itself is not managed by CDI - only
> injected with CDI objects. This is also more or less what I
> personally need for weld/cdi+jersey. (no need to have jersey
> controllers CDI managed actually).
>

If you want that then just annotate with @ManagedBean. There will
still be issues with constructor injection though, and of course you
are using Jersey's DI support to manage the life-cycle :-)


>> By default JAX-RS resource classes are managed in the
>> request scope. This actually requires more CDI magic to
>> modify the internal model such that the scope of a resource
>> class is modified from being dependent to being request
>> scoped. We need to address this as well as better @Inject
>> support.
>
> Ok. Thanks for the info. I will make sure my controllers are
> singletons if possible to avoid problems then.
>

It does not matter, make them request scoped or application scoped.
The point is, as you state later, you need to annotate.


>>> Instead you should react on the presense of
>> "beans.xml" like Weld and assume that all beans are mananged
>> by CDI/weld if present.
>>>
>>
>> Jersey does already. That is what the CDI extension
>> registration does so that processor injection targets can be
>> adapted. Jersey defers to CDI for instantiate when CDI is
>> present.
>
> If jersey does then, then why do I ALSO need to annotate jersey
> controllers with CDI/javax.inject stuff in order for jersey to
> support injecting CDI managed objects into jersey controllers ?
>

Because enabling CDI changes the programming model. It means that
adding a beans.xml may result in deployment failure for existing JAX-
RS code. So i took the conservative approach of "keep on trucking" and
your resource classes will behave in exactly the same way unless you
explicitly declare otherwise.

For example if you have the existing resource class:

@Path("/foo")
public class FooResource {
   private final String p;

   public FooResource(@QueryParam("p") String p) {
     this.p = p;
   }
}

In the above the scope is required to be per-request as specified by
JAX-RS. For such a scope CDI will require a default constructor (due
to client proxy requirements for such a scope).

So even if, and i am not sure it is possible, Jersey can magically
modify the CDI model to support the the scope and injection of the
constructor parameter (without the constructor annotated with @Inject,
i cannot recall if CDI requires it or not for one constructor) it will
still result in deployment failure [*].

As i said this area is very complex.


>> There is also the case when CDI is not present and
>> @ManagedBean is utilized. This means Jersey defers to the
>> container to instantiate, inject, then Jersey injects, then
>> Jersey manages the life-cycle. As i said this whole area is
>> complex.
>
> Yes where - that's why we need some documentation or even BETTER
> removing all that complexity alltogether by removing jersey's own
> dependency manager stuff :-)
>

The point about what i wrote above is it may not be totally possible
because CDI may not always be configured (no beans.xml) and
@ManagedBean is required to be supported by JAX-RS in EE 6.

Paul.

[*] FWIW this is less of an issue for Guice, unless you explicitly use
AOP.