users@jersey.java.net

[Jersey] Re: CDI in filters and exception mappers

From: Jakub Podlesak <jakub.podlesak_at_oracle.com>
Date: Tue, 7 Jan 2014 15:16:38 +0100

Hi Pedro,

This becomes a little bit tricky.

You have set the ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE to true,
which means the CDI integration code does not get activated at all. At the moment,
i do not know of any way how to keep the above setting while having the Jersey/CDI integration
active. Component providers are being invoked in an early stage of application bootstrap process,
so it would not help if you just introduce an appropriate HK2 binding (not to mention respective
implementation class is part of Jersey internal API, so you should avoid using it in your code anyway).

I guess you got rid of META-INF/services lookup in order to configure recent Jackson JSON provider.
I know it is not an ideal solution, but you could probably just repackage Jackson provider jar file
to exclude the META-INF/services files as a temporary workaround until this annoying thing gets fixed.

On the “provider injection should behave the same as resource class injection”: there was indeed a bug in Jersey
related to this. That bug has been fixed in Jersey version 2.2 (see [1]). To make sure you have the right (patched)
version of GF, i would recommend you download from [2].

Thanks,

~Jakub

[1]https://java.net/jira/browse/JERSEY-1997
[2]http://dlc.sun.com.edgesuite.net/glassfish/4.0.1/nightly/latest-glassfish-ml.zip

P.S. As a side effect, i have found another issue in Jersey/EJB integration layer,
that i have filed here: https://java.net/jira/browse/JERSEY-2320

On 07 Jan 2014, at 01:46, Pedro Nuno Santos <pedro-n-santos_at_ptinovacao.pt> wrote:

> Hi Jakub,
>
> I’ve uploaded a small project to my github account (https://github.com/pnsantos/jersey-cdi). It’s a simple REST application with a single resource, a container request filter and an exception mapper. I’m running it in Glassfish 4.0 (but I can later try it out in 4.0.1 too).
>
> As it is, it should be deployable and always return 501 when you access /api
>
> I’m having several problems regarding CDI, in the filter and exception mapper. I’m trying to inject:
> - a Logger using the @Produces annotation (in org.example.cdi.logging.LoggerProducer)
> - a simple POJO (org.example.cdi.bean.MyPojo)
> - a singleton (org.example.cdi.bean.SingletonBean)
>
> I don’t know if I’m doing anything wrong but here’s what I’ve been able to verify until now
>
> 1) The POJO, Singleton and Logger are injected into the resource without issue
> 2) The Singleton is always null (i.e. injection fails) in both the filter and exception mapper
> 3) If I register the POJO using the AbstractBinder it’s injected fine into both the filter and exception mapper
> 4) If I don’t register the POJO using AbstractBinder then injection fails and I can’t even deploy the application (hk2 give the unsatisfied dependency exception)
> 5) Whether I register the Singleton or not doesn’t make a diference (it’s always null in both the filter and exception mapper)
> 6) Trying to Inject the Logger in either the filter or the exception mapper causes a hk2 unsatisfied exception on deployment
>
> I’m assuming that the behaviour of both the filter and exception mapper should be just like the resource? i.e. I should be able to inject into the filter and exception mapper the Logger, POJO and Singleton without any “tricks” just like I currently doing in the resource right?
>
>
> Cheers,
> Pedro
>
> From: Jakub Podlesak [mailto:jakub.podlesak_at_oracle.com]
> Sent: 06 January 2014 15:39
> To: users_at_jersey.java.net
> Subject: [Jersey] Re: CDI in filters and exception mappers
>
> Hi Pedro,
>
> Your understanding is correct. You should be able to inject using @Inject
> into filters/exception mappers without any issues. Otherwise it is a bug.
> I suspect something could be wrong with your producer, but i might be mistaken.
> In that case i would need some more information, ideally a reproducible test case.
>
> The HK2 exception that you see suggests that CDI does not know about your CDI producer.
> Have you tried to just inject e.g. a raw CDI singleton bean (no CDI producer involved)?
> Did it work?
>
> In any way, could you please provide some more details on your injection point
> and the producer that you believe should satisfy the injection point?
>
> How do you register the producer? One way to do so, is to
> 1) implement you own CDI Extension
> 2) make the extension implement a “before bean discovery hook” like so:
> @SuppressWarnings("unused")
> private void beforeBeanDiscovery(@Observes BeforeBeanDiscovery beforeBeanDiscovery, BeanManager beanManager) {
> beforeBeanDiscovery.addAnnotatedType(beanManager.createAnnotatedType(YourLoggerProducer.class));
> }
>
> Does the above fix your problem?
>
> ~Jakub
>
> On 20 Dec 2013, at 11:55, Pedro Nuno Santos <pedro-n-santos_at_ptinovacao.pt> wrote:
>
>
> Hi,
>
> I’m not an expert on CDI (just learning the ropes) and I could be doing something wrong but shouldn’t I be able to use @Inject inside filters and/or exception mappers?
>
> I’ve tried both with glassfish 4.0 and 4.0.1 (using jersey 2.4.1) but injection only works inside resources. In both filters and exception mappers I get the following exception on deployment:
>
> org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee (…)
>
> The only solution I found was to use AbstractBinder to register the classes to be injected, however that doesn’t work if the object creation is being done using the @Produces annotation (I’m trying to inject a Logger instance and I need access to the class name where it’s injected, from what I can gather the hk2 Factories don’t allow me to access that information).
>
> I remember once reading in the documentation that any class annotated with “@Provider” supported CDI but I can’t seem to find the phrase anymore…
>
>
> Cheers,
> Pedro