Problems with dependency injection in java / jersey / h2k

276 views Asked by At

Im having some problems with dependency injections in java 11 / jersey / hk2. I have a simple resource class which injects a service class:

@Path("/backbone")
public class BackboneController extends GenericController {
    @Inject
    private IEnvironmentService _environmentService;
    @Inject
    private IAuthenticationHelper _authenticationHelper;
    @Inject
    private IBackboneService _backboneService;

    @GET
    @Path("version")
    @Produces(MediaType.APPLICATION_JSON)
    public Response version(
            @HeaderParam("Authorization") String token) throws Exception {
        var credentials = _authenticationHelper.detokenizeCredentials(token);

        var backendVersionHandler = new BackendVersionResponseDto(_backboneService.getBackendVersion(credentials));

        var apiVersionHandler = new Properties();
        apiVersionHandler.load(BackboneController.class.getResourceAsStream("/project.properties"));

        return Response.status(Status.OK)
                .entity(new GenericResponse(
                        new VersionResponseDto(backendVersionHandler.getBackend(),
                                apiVersionHandler.getProperty("version"))))
                .build();
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("url")
    public Response getUrl(
            @HeaderParam("Authorization") String token) throws Exception {
        var credentials = _authenticationHelper.detokenizeCredentials(token);

        var urlDto = new UrlResponseDto(_backboneService.getUrl(credentials));

        return Response.status(Status.OK).entity(new GenericResponse(urlDto)).build();
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("context-path-to-etc")
    public Response getContextPathToEtc(
            @HeaderParam("Authorization") String token) throws Exception {
        var credentials = _authenticationHelper.detokenizeCredentials(token);

        if (!_backboneService.areCredentialsValid(credentials))
            throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());

        var contextPathToEtcDto = new ContextPathToEtcResponseDto(_environmentService.getEtcPathInContext());

        return Response.status(Status.OK).entity(new GenericResponse(contextPathToEtcDto)).build();
    }
}

The problem is related with the IEnvironmentService, which injects IEnvironmentRepository. Here are the interface and the class itself:

@Contract
public interface IEnvironmentService {
    public void environmentSet(Credentials credentials, String key, String value) throws Exception;
    public void environmentUnset(Credentials credentials, String key) throws Exception;
    public String environmentGet(Credentials credentials, String key) throws Exception;
    public String getEtcPathInContext();
}

@Service
public class EnvironmentService implements IEnvironmentService {
    @Inject
    private EnvironmentRepository _environmentRepository;

    @Override
    public void environmentSet(Credentials credentials, String key, String value) throws Exception {
        _environmentRepository.environmentSet(credentials, key, value);
    }

    @Override
    public void environmentUnset(Credentials credentials, String key) throws Exception {
        _environmentRepository.environmentUnset(credentials, key);  
    }

    @Override
    public String environmentGet(Credentials credentials, String key) throws Exception {
        return _environmentRepository.environmentGet(credentials, key);
    }

    @Override
    public String getEtcPathInContext() {
        return _environmentRepository.getEtcPathInContext();
    }
}

IEnvironmentRepository and EnvironmentRepository here:

@Contract
public interface IEnvironmentRepository {
    public void environmentSet(Credentials credentials, String key, String value) throws Exception;
    public void environmentUnset(Credentials credentials, String key) throws Exception;
    public String environmentGet(Credentials credentials, String key) throws Exception;
    public String getEtcPathInContext();
}


@Service
public class EnvironmentRepository extends GenericRepository implements IEnvironmentRepository {  
    @Inject
    private IContextFinder _contextFinder;
      
    @Override
    public void environmentSet(Credentials credentials, String key, String value) throws Exception {
        _connector.execute(credentials.getUsername(), credentials.getPassword(),
                String.format("SELECT backbone.environment_set(%s, %s)'", new SqlParameter("p_key", key),
                        new SqlParameter("p_value", value)));
    }

    @Override
    public void environmentUnset(Credentials credentials, String key) throws Exception {
        _connector.execute(credentials.getUsername(), credentials.getPassword(),
                String.format("SELECT backbone.environment_unset(%s)", new SqlParameter("p_key", key)));
    }

    @Override
    public String environmentGet(Credentials credentials, String key) throws Exception {
        return _connector.queryText(credentials.getUsername(), credentials.getPassword(),
                String.format("SELECT backbone.environment_get(%s)", new SqlParameter("p_key", key)));
    }

    @Override
    public String getEtcPathInContext() {
        return _contextFinder.getEtcPathInContext();
    }
}

And at last, the abstract binder and the resource config:

public class BackboneBinder extends AbstractBinder {
    @Override
    protected void configure() { 
        bind(BackboneRepository.class).to(IBackboneRepository.class);
        bind(BackboneService.class).to(IBackboneService.class);
        bind(EnvironmentRepository.class).to(IEnvironmentRepository.class).in(PerLookup.class);     
        bind(EnvironmentService.class).to(IEnvironmentService.class); 
        bind(ContextFinder.class).to(IContextFinder.class);
        bind(ParametersHandler.class).to(IParametersHandler.class); 
        bind(AuthenticationHelper.class).to(IAuthenticationHelper.class);
    }
}

public class ApplicationConfiguration extends ResourceConfig {
    public ApplicationConfiguration() {
        // Dependencies binders 
        register(new BackboneBinder());

        packages("com.bfaconsultora");
    }
}

Now, when I consume the resource via postman, I get the following error:

javax.servlet.ServletException: A MultiException has 5 exceptions.  They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=EnvironmentRepository,parent=EnvironmentService,qualifiers={},position=-1,optional=false,self=false,unqualified=null,804331421)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.bfaconsultora.rest.backbone.services.EnvironmentService errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on com.bfaconsultora.rest.backbone.services.EnvironmentService
4. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.bfaconsultora.rest.backbone.controllers.BackboneController errors were found
5. java.lang.IllegalStateException: Unable to perform operation: resolve on com.bfaconsultora.rest.backbone.controllers.BackboneController

    org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:408)
    org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:365)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:318)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)

I'm really lost with this. If I remove the injection of the IEnvironmentRepository in the EnvronmentService class, and replace it with a regular new EnvironmentRepository() everything works OK. The strange thing is that with Backbone Service and Repository, which are very similar to Environment stuff, injection works just fine.

Could you please point me in the right direction?

Thank you in advance.

Regards

0

There are 0 answers