Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection in jersey 2.17

I have a resource class

@Path("/rest")
public class DemoResourceController {
    @Inject
    DemoService demoService;

    @Path("/get/demo")
    @GET
    @Produces(APPLICATION_JSON)
    public Response getDemoLists() {
        List<String> demoList=demoService.getDemoList();
        return  Response.ok(demoList).build();
    }

I tried the answers in the post Dependency injection with Jersey 2.0

if i use

compile group: "org.glassfish.jersey.ext.cdi" , name: "jersey-cdi1x" , version: "2.17"
compile group: "org.glassfish.jersey.ext.cdi" ,name: "jersey-weld2-se" , version: "2.17"

On launching the server i get

org.jboss.weld.exceptions.IllegalArgumentException: WELD-001408: 
Unsatisfied dependencies for type demoService with qualifiers @Default
[BackedAnnotatedField] @Inject  DemoResourceController.demoService at injection point

If i remove the above dependencies then i get

javax.servlet.ServletException: A MultiException has 3 exceptions.  They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no
   object available for injection at SystemInjecteeImpl(requiredType=DemoService,parent=DemoResourceController,qualifiers={},position=- 1,optional=false,self=false,unqualified=null,1952079126)**
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of DemoResourceController errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on package.DemoResourceController

org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:421)

The resourceconfig class is

public class ApplicationConfig extends ResourceConfig {

  public ApplicationConfig() {
    register(new ApplicationBinder());
    packages(..name of packages..);
  }

The binder class is

public class ApplicationBinder extends AbstractBinder{
  @Override
  protected void configure() {
      bind(DemoService.class).to(DemoServiceImpl.class);
  }
 }

I use tomcat in embedded mode and add init parameters

Context ctx = tomcat.addContext("/", new File("web-app").getAbsolutePath());
Wrapper wrapper = ctx.createWrapper();
wrapper.addInitParameter("javax.ws.rs.Application","xx.xx.ApplicationConfig");

How do i inject the service in the controller? Is injection the preferred way to unit test it (when the service implementation,say demoServiceImpl is calling another service say,XService) and unit tests should not depend on Xservice and hence demoServiceImpl How would i inject a mock of the service into the controller from the test?

like image 541
bl3e Avatar asked Feb 02 '26 18:02

bl3e


1 Answers

In your second attempt (without the cdi dependencies; using HK2) your binding is incorrect. It should be

bind(Implementation).to(Contract)
// - i.e.
bind(DemoServiceImpl.class).to(DemoService.class);

You have it the other way around.

As far as testing, if you have the test in same package (in the test area of the project) you should be able to assign the service, as it's package private. Though personally, I've gotten into the habit of constructor injection. Another thing you can do is use Jersey Test Framework. You can see an complete example here, where a mock service is injected

like image 65
Paul Samsotha Avatar answered Feb 04 '26 09:02

Paul Samsotha



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!