title: Jersey & Spring managed providers
body: <p>I'm using <strong>Jersey 2.4.1</strong>, <strong>Spring 3.2.4</strong> and <strong>Jetty 7</strong>.</p>
  
  <p>I don't understand how Jersey registers providers that are managed by Spring.
  My classes annotated with <code>@Provider</code> are also annotated <code>@Component</code> because I need injection.
  I configured Jersey to scan my packages with these providers.</p>
  
  <p>Here is how I configure Jersey servlet:</p>
  
  <pre><code>public void createJerseyServlet() {
    ResourceConfig resourceConfig = new ResourceConfig();
    resourceConfig.packages("test.web", "org.glassfish.jersey.server.spring");
    resourceConfig.register(LoggingFilter.class);
    ServletHolder servletHolder = new ServletHolder(new ServletContainer(resourceConfig));
    servletContextHandler.addServlet(servletHolder, "/*");
  }
  </code></pre>
  
  <p>The logs at startup:</p>
  
  <pre><code>INFO - org.glassfish.jersey.server.spring.SpringComponentProvider - Spring context lookup done.
  INFO - org.glassfish.jersey.server.spring.SpringComponentProvider - Spring component provider initialized.
  INFO - org.glassfish.jersey.server.spring.SpringComponentProvider - Spring managed bean, testResource, registered with HK2.
  INFO - org.glassfish.jersey.server.spring.SpringComponentProvider - Spring managed bean, nullPointerExceptionMapper, registered with HK2.
  INFO - org.glassfish.jersey.server.spring.SpringComponentProvider - Spring managed bean, filterTest, registered with HK2.
  [...]
  INFO - org.glassfish.jersey.server.ApplicationHandler - Jersey application initialized.
  Root Resource Classes:
    org.obiba.jta.web.TestResource
  Pre-match Filters:
     org.glassfish.jersey.filter.LoggingFilter
  Global Response Filters:
     org.glassfish.jersey.filter.LoggingFilter
  Global Reader Interceptors:
     org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor
  Global Writer Interceptors:
     org.glassfish.jersey.filter.LoggingFilter
  [...]
  </code></pre>
  
  <p>My providers are detected via Spring: <code>Spring managed bean, filterTest, registered with HK2</code> but they don't appear in the <code>ApplicationHandler</code> logs...
  And they are not used when I run the application.</p>
  
  <p>I need to manually register them:</p>
  
  <pre><code>@Resource
  private FilterTest filterTest;
  
  @Resource
  private MyExceptionMapper myExceptionMapper;
  
  [...]
  
  resourceConfig.register(filterTest);
  resourceConfig.register(myExceptionMapper);
  </code></pre>
  
  <p>Or even better... for a workaround :(</p>
  
  <pre><code>Map&lt;String, Object&gt; providers = applicationContext.getBeansWithAnnotation(Provider.class);
  for(Object provider : providers.values()) {
    resourceConfig.register(provider);
  }
  </code></pre>
  
  <p>Now it works (even if they still don't appear in <code>ApplicationHandler</code> logs) but I don't understand why Jersey does not register them automatically when it scans the package and see that these bean are managed by Spring...</p>
  
  <hr>
  
  <p>Here are my components...</p>
  
  <h3>Resource</h3>
  
  <pre><code>package test.web;
  
  @Transactional
  @Component
  @Path("/test")
  public class TestResource {
    @Resource
    private MyService myService;
  
    @GET
    @Path("/inject")
    @Produces(MediaType.TEXT_PLAIN)
    public String testInjection() {
      return "integrationService: " + integrationService;
    }
  
    @GET
    @Path("/active")
    @Produces(MediaType.TEXT_PLAIN)
    public String testActiveTransaction() {
      return "isActualTransactionActive: " + TransactionSynchronizationManager.isActualTransactionActive();
    }
  
    @GET
    @Path("/exception")
    @Produces(MediaType.TEXT_PLAIN)
    public String testException() {
      throw new MyException();
    }
  }
  </code></pre>
  
  <h3>Filter</h3>
  
  <pre><code>package test.web.cfg;
  
  @Provider
  @Component
  public class FilterTest implements ContainerRequestFilter {
    @Resource
    private MyService myService;
    [...]
  }
  </code></pre>
  
  <h3>ExceptionMapper</h3>
  
  <pre><code>package test.web.cfg;
  
  @Provider
  @Component
  public class MyExceptionMapper implements ExceptionMapper&lt;MyException&gt; {
    @Override
    public Response toResponse(MyException exception) {
      return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("MyException was thrown!").build();
    }
  }
  </code></pre>
  
  <h3>And finally my dependencies</h3>
  
  <pre><code>compile("org.glassfish.jersey.core:jersey-common:2.4.1")
  compile("org.glassfish.jersey.core:jersey-server:2.4.1")
  compile("org.glassfish.jersey.containers:jersey-container-servlet-core:2.4.1")
  compile("org.glassfish.jersey.media:jersey-media-multipart:2.4.1")
  compile("org.glassfish.jersey.connectors:jersey-apache-connector:2.4.1")
  compile("org.glassfish.jersey.ext:jersey-spring3:2.4.1")
  </code></pre>