title: How to integrate JAX-RS with CDI in a Servlet 3.0 container
body: <p>I have a web application running on a Servlet 3.0 container (Jetty 9.0.4) using JSF 2.2 (Mojorra 2.1.3) &amp; CDI 1.1 (Weld 2.0.3). No full-fledged application server is used. In this application I also have a JAX-RS 2.0 (Jersey 2.2) resource class serving REST requests. I have integrated JAXB binding and also JSON marshalling (Jackson 2.2). I use Maven 3.0.5 for the build management. These are the relevant parts of my project setup:</p>
  
  <p>Maven pom.xml:</p>
  
  <pre class="lang-xml prettyprint-override"><code>...
  &lt;dependencies&gt;
  
      &lt;!-- Servlet 3.0 API --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
          &lt;artifactId&gt;javax.servlet-api&lt;/artifactId&gt;
          &lt;version&gt;3.1.0&lt;/version&gt;
          &lt;scope&gt;provided&lt;/scope&gt;
      &lt;/dependency&gt;
  
      &lt;!-- Contexts and Dependency Injection for Java EE --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.jboss.weld.servlet&lt;/groupId&gt;
          &lt;artifactId&gt;weld-servlet&lt;/artifactId&gt;
          &lt;version&gt;2.0.3.Final&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;!-- JavaServer Faces --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;com.sun.faces&lt;/groupId&gt;
          &lt;artifactId&gt;jsf-api&lt;/artifactId&gt;
          &lt;version&gt;2.2.2&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;com.sun.faces&lt;/groupId&gt;
          &lt;artifactId&gt;jsf-impl&lt;/artifactId&gt;
          &lt;version&gt;2.2.2&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;!-- JAX-RS RESTful Web Services --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.glassfish.jersey.containers&lt;/groupId&gt;
          &lt;artifactId&gt;jersey-container-servlet&lt;/artifactId&gt;
          &lt;version&gt;2.2&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;!-- JSON Mapping Framework --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
          &lt;artifactId&gt;jackson-databind&lt;/artifactId&gt;
          &lt;version&gt;2.2.2&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.glassfish.jersey.media&lt;/groupId&gt;
          &lt;artifactId&gt;jersey-media-json-jackson&lt;/artifactId&gt;
          &lt;version&gt;2.2&lt;/version&gt;
      &lt;/dependency&gt;
  &lt;/dependencies&gt;
  ...
  </code></pre>
  
  <p>Deployment Descriptor web.xml:</p>
  
  <pre class="lang-xml prettyprint-override"><code>...
  &lt;context-param&gt;
      &lt;param-name&gt;javax.faces.PROJECT_STAGE&lt;/param-name&gt;
      &lt;param-value&gt;Development&lt;/param-value&gt;
  &lt;/context-param&gt;
  
  &lt;servlet&gt;
      &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
      &lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt;
      &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
  &lt;/servlet&gt;
  
  &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/jsf/*&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  
  &lt;servlet&gt;
      &lt;servlet-name&gt;Jersey REST Service&lt;/servlet-name&gt;
      &lt;servlet-class&gt;org.glassfish.jersey.servlet.ServletContainer&lt;/servlet-class&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;javax.ws.rs.Application&lt;/param-name&gt;
          &lt;param-value&gt;my.package.config.RestApplication&lt;/param-value&gt;
      &lt;/init-param&gt;
      &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
  &lt;/servlet&gt;
  
  &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;Jersey REST Service&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/rest/*&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;  
  
  &lt;session-config&gt;
      &lt;session-timeout&gt;30&lt;/session-timeout&gt;
  &lt;/session-config&gt;
  
  &lt;listener&gt;
      &lt;listener-class&gt;org.jboss.weld.environment.servlet.Listener&lt;/listener-class&gt;
  &lt;/listener&gt;
  
  &lt;listener&gt;
      &lt;listener-class&gt;com.sun.faces.config.ConfigureListener&lt;/listener-class&gt;
  &lt;/listener&gt;
  
  &lt;resource-env-ref&gt;
      &lt;description&gt;Object factory for the CDI Bean Manager&lt;/description&gt;
      &lt;resource-env-ref-name&gt;BeanManager&lt;/resource-env-ref-name&gt;
      &lt;resource-env-ref-type&gt;javax.enterprise.inject.spi.BeanManager&lt;/resource-env-ref-type&gt;
  &lt;/resource-env-ref&gt;
  ...
  </code></pre>
  
  <p>JAX-RS root resource class:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Path("/person")
  public class PersonController
  {
      @Inject
      private PersonService personService;
  
      @GET
      @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
      public List&lt;Person&gt; getAllPersons()
      {
          return personService.getAll();
      }
  
      @GET
      @Path("/{index}")
      @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
      public Person getPerson(@PathParam("index") int index)
      {
          return personService.get(index);
      }
  
      @POST
      @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
      public void savePerson(Person person)
      {
          personService.add(person);
      }
  }
  </code></pre>
  
  <p>JAX-RS application configuration:</p>
  
  <pre class="lang-java prettyprint-override"><code>public class RestApplication extends ResourceConfig
  {
      public RestApplication()
      {
          // For JSON binding
          register(new JacksonFeature());
          register(new ApplicationBinder());
          packages("my.package.controller");
      }
  }
  </code></pre>
  
  <p>JAX-RS injection binding configuration:</p>
  
  <pre class="lang-java prettyprint-override"><code>public class ApplicationBinder extends AbstractBinder
  {
      @Override
      protected void configure()
      {
          // Means something like: bind the field at an injection point of type PersonService to an instance of type PersonService
          bind(PersonService.class).to(PersonService.class);
      }
  }
  </code></pre>
  
  <p>And finally the JSF managed bean:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Named
  @SessionScoped
  public class PersonBean implements Serializable
  {
      private static final long serialVersionUID = 1L;
  
      @Inject
      private PersonService personService;
  
      private Person newPerson = new Person();
  
      public List&lt;Person&gt; getAll()
      {
          return personService.getAll();
      }
  
      public Person getNewPerson()
      {
          return newPerson;
      }
  
      public void setNewPerson(Person newPerson)
      {
          this.newPerson = newPerson;
      }
  
      public Gender[] getGenders()
      {
          return Gender.values();
      }
  
      public String saveNewPerson()
      {
          personService.add(newPerson);
          newPerson = new Person();
  
          return "index";
      }
  }
  </code></pre>
  
  <p><strong>At the end, I want to be able to use the same application scoped service instances in the REST resource classes as well as in the JSF beans, but I can't get CDI and JAX-RS work together.</strong></p>
  
  <p>The JSF/CDI part works fine, but the injection into the REST resource classes does not really work. I read some articles, where they showed two different approaches to combine CDI and JAX-RS: The first one is to annotate the REST resource class with <code>@ManagedBean</code> in order for the class to be instantiated by the CDI container and to be managed by the JAX-RS container:</p>
  
  <pre class="lang-java prettyprint-override"><code>@ManagedBean
  @Path("/person")
  public class PersonController
  {
      @Inject
      private PersonService personService;
      ...
  </code></pre>
  
  <p>The second approach is to give the class a CDI scope, e.g. <code>@RequestScoped</code> in order for the class to be instantiated and managed by the CDI container.</p>
  
  <pre class="lang-java prettyprint-override"><code>@Path("/person")
  @RequestScoped
  public class PersonController
  {
      @Inject
      private PersonService personService;
      ...
  </code></pre>
  
  <p>None of the approaches work for me. I always end up with the following exception:</p>
  
  <pre class="lang-java prettyprint-override"><code>org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=PersonService,parent=PersonController,qualifiers={}),position=-1,optional=false,self=false,unqualified=null,5643079)
      at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)
      at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:208)
      at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:231)
      at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:328)
      at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:454)
      at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:158)
      at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2296)
      at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:590)
      at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:577)
      at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:172)
  </code></pre>
  
  <p>But this error disappears when changing the injection binding configuration to:</p>
  
  <pre class="lang-java prettyprint-override"><code>bind(PersonServiceImpl.class).to(PersonService.class);
  </code></pre>
  
  <p>Now injection somehow works, but for every REST request I get a new instance of the <code>PersonServiceImpl</code> injected, even if this service is application scoped. To me this is an indicator, that the JAX-RS component is totally separated from the CDI stuff and lives in a completely different environment or container as the CDI / JSF stuff does.</p>
  
  <p>So I really wonder how to make these two concepts work together in a pure servlet 3.0 container.</p>