1

I am trying to inject service in spring boot app. However I'm getting following error:

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=RecommendationService,parent=RecommendationResourceImpl,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1163111460)

Here is the code:

package com.example.test.recommendations.resources;    

@Provider
public class RecommendationResourceImpl implements RecommendationResource {

@Inject
private RecommendationService recommendationService;

@Override
public List<Recommendation> get(String currency,
                                String entity) {
    return recommendationService.getRecommendations(currency, entity));
  }
}

Service interface

package com.example.test.recommendations.resources;

// imports

public interface RecommendationService {
    List<Recommendation> getRecommendations(String currency, String entity);

    Recommendation get(UUID uuid);
}

Service implementation

package com.example.test.recommendations.resources;

//imports

@Component
public class RecommendationServiceImpl implements RecommendationService{
    @Override
    public List<Recommendation> getRecommendations(String currency, String entity) {
        return Collections.emptyList();
    }

    @Override
    public Recommendation get(UUID uuid) {
        return null;
    }
}

What is correct way to inject services in spring boot applications?

I am using spring boot version 1.3.8 and Jersey version 2.25.1

2 Answers2

0

From your stacktrace it is evident that the server cannot find the dependency bean to be injected.So initially check that the desired bean for the class is getting created during applciation start up.Verify that the service class is in the classpath for component scan to take place, otherwise include the package for scanning.

You are using the @Inject annotation instead of the spring @Autowired annotation to inject the beans.It will work fine but the first and most important difference between @Autowired and @Inject annotation is that the @Inject annotation is only available from Spring 3.0 onwards, so if you want to use annotation-driven dependency injection in Spring 2.5 then you have to use the @Autowired annotation.

Secondly, use the annotation @Service for the service layer rather than using the @Component annotation.

Indicates that an annotated class is a "Service", originally defined by Domain-Driven Design (Evans, 2003) as "an operation offered as an interface that stands alone in the model, with no encapsulated state."

May also indicate that a class is a "Business Service Facade" (in the Core J2EE patterns sense), or something similar. This annotation is a general-purpose stereotype and individual teams may narrow their semantics and use as appropriate.

This annotation serves as a specialization of @Component, allowing for implementation classes to be autodetected through classpath scanning.

@Service
public class RecommendationServiceImpl implements RecommendationService{
    @Override
    public List<Recommendation> getRecommendations(String currency, String entity) {
        return Collections.emptyList();
    }

    @Override
    public Recommendation get(UUID uuid) {
        return null;
    }
}

I am not an expert on using jersey with springboot , so i do not know if any configurations are causing this issue.

Maybe this thread might be of help to you more: Dependency injection with Jersey 2.0

Ananthapadmanabhan
  • 5,706
  • 6
  • 22
  • 39
0

You probably never registered your Service with the DI-container. You can do that in your ResourceConfig, which you probably have since you are using jersey:

public class MyApplication extends ResourceConfig {
    public MyApplication() {
        register(new org.glassfish.hk2.utilities.binding.AbstractBinder() {

            @Override
            protected void configure() {
                bind(RecommendationServiceImpl.class).to(RecommendationService.class).in(Singleton.class);
            }
        });

        packages("com.example.test.recommendations.resources");
    }
}

I am using hk2 without spring, so I usually annotate my interfaces with org.jvnet.hk2.annotations.Contract and the implementations with org.jvnet.hk2.annotations.Service. (note: not the spring @Service annotation), so I recommend trying that as well.

sfiss
  • 2,119
  • 13
  • 19