users@jersey.java.net

[Jersey] Re: CDI in filters and exception mappers

From: Pedro Nuno Santos <pedro-n-santos_at_ptinovacao.pt>
Date: Tue, 7 Jan 2014 19:00:48 +0000

Just a small follow up. It seems the real reason the scanning was disabled was because otherwise my custom ContextResolver is ignored by Jersey (it's registered but it's never used). I found a thread [1] concerning this issue and removing, as you suggested, the META-INF/services folder does indeed solve the problem.

In the meantime I opened an issue with Jackson [2], maybe they can change it on their end.

[1] https://java.net/projects/jersey/lists/users/archive/2013-12/message/67

[2] https://github.com/FasterXML/jackson-jaxrs-providers/issues/39


Cheers,
Pedro

From: Pedro Nuno Santos
Sent: 07 January 2014 15:07
To: users_at_jersey.java.net
Subject: [Jersey] Re: CDI in filters and exception mappers

Thanks for all the help Jakub!

I've re-enabled the metainf lookup and the logger and pojo injection are now working fine in glassfish 4.0.1. Nice!

I disabled scanning because the Jackson provider included their own exception mapper for some JSON parsing exceptions which sometimes got registered first than my own mappers (more details in [1]). Anyway I think I can figure out another way around that (I think extending those classes and overriding the methods also works, it's less "clean" but works).

Once again thanks for the help!

[1] https://github.com/FasterXML/jackson-jaxrs-providers/issues/22


Cheers,
Pedro

From: Jakub Podlesak [mailto:jakub.podlesak_at_oracle.com]
Sent: 07 January 2014 14:17
To: users_at_jersey.java.net<mailto:users_at_jersey.java.net>
Subject: [Jersey] Re: CDI in filters and exception mappers

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<mailto: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<mailto: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<mailto: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