5

So, I have a tomcat 8 + jersey 2.5.1 + weld CDI app that works very well in most cases. Where it fails is that I am unable to intercept jersey resource method calls with a CDI interceptor. This makes sense because a jersey resource class is not a CDI bean. Then, is there any way to make a CDI interceptor work in jersey? Another way to ask this question: Can a CDI bean be used as a Jersey resource?

Thanks!

EDIT: Before I wrote my RESTful resources using Jersey, I had CDI interceptors that were used to begin and commit database transactions. I really need to follow the same or similar pattern to implement this cross-cutting transaction injection in my RESTful jersey resources. That is the main reason for asking this question.

Thanks again!

doles
  • 558
  • 6
  • 20
  • YOu should be able to use a CDI bean as a Jersey resource, in an EE container. In Tomcat (servlet container) it's a little more difficult since it's not built in. Per this bug, it should work: https://java.net/jira/browse/JERSEY-883 – John Ament Jan 23 '14 at 14:29
  • Thanks. That bug does say that CDI interceptors should work. – doles Jan 23 '14 at 18:47
  • I got rid of jersey in my app and replaced it with straight servlets. Now, things work as they should and I dont have to deal with the ResourceConfig crud. Additionally, I dont have to deal with https://java.net/jira/browse/HK2-181 and can use lambda expressions in my java8 code. Thanks to everyone who attended this question! – doles Jan 24 '14 at 02:04

2 Answers2

2

Can a CDI bean be used as a Jersey resource?

Yes, but since Jersey's DI is based on hk2 and not CDI, you need a bridge.

In glassfish such a bridge is realized by the module jersey-gf-cdi:

<dependency>
    <groupId>org.glassfish.jersey.containers.glassfish</groupId>
    <artifactId>jersey-gf-cdi</artifactId>
    <version>2.6</version>
</dependency>

The module registers itself automatically and works on Tomcat beautifully (assuming you have correctly bootstrapped both Jersey and Weld).

Unfortunately, the versions before 2.6 relies on JNDI only, searching the provider under 'java:comp/BeanManager' which Tomcat does not allow.

A fix for this behaviour is available for 2.6 (a pull request I made some time ago), and falls back on CDI.current().getBeanManager().

I tested it on Tomcat 7 and works correctly, should work on Tomcat 8 too.

Carlo Pellegrini
  • 5,656
  • 40
  • 45
  • Thank you. I have given up on tomcat and cdi in tomcat I now use JBoss and everything works the way it's supposed to, out of the box. – doles Feb 28 '14 at 19:26
  • I cannot fix this.When I change the version to 2.6 this error ocurrs: WELD-001409: Ambiguous dependencies for type "X". How did you fix this? – Vinicius de Souza Mar 24 '16 at 02:49
0

Adam Bien in one presentation recommends that you separate your Service (CDI or EJB) class from your RESTful resources class. His reason was that the RESTful class usually uses the HttpHeaders injected by Jersey yet not available in the CDI or EJB containers. The hazard is that your RESTful classes could be injected a Null reference of HttpHeaders if any CDI client like the JSF framework uses it.

Thanks to your self-answered question. You have just showed a second use case that validates Adam Bien's recommendation.

Simply keep them apart!

Sym-Sym
  • 3,578
  • 1
  • 29
  • 30
  • I'm not sure how this answers the question. For example, one use I have today is a CDI interceptor on certain REST APIs that checks for an active user login before activating the REST resource. – John Ament Jan 23 '14 at 14:22
  • Yeah, even I am not sure how this answers the question. – doles Jan 23 '14 at 19:02