I have the following implementation for a Jersey (2.18) application:
public class RootApplication extends ResourceConfig {
public RootApplication() {
packages("com.foo.bar");
register(new AbstractBinder() {
@Override
protected void configure() {
bindFactory(RepositoryFactory.class).to(Repository.class);
// if I use following line instead of bindFactory it works
// bind(OracleRepository.class).to(Repository.class);
}
});
}
public class RepositoryFactory implements Factory<Repository> {
private final Repository repo;
public RepositoryFactory() {
this.repo = new OracleRepository();
}
@Override
public Repository provide() {
return repo;
}
@Override
public void dispose(Repository repo) {
}
}
}
and get the exception below when hitting a service that injects Repository
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=Repository,parent=MeasureService,qualifiers={},position=-1,optional=false,self=false,unqualified=null,56464420)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.fidelity.pi.dashboard.rest.MeasureService errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on com.fidelity.pi.dashboard.rest.MeasureService
It all works if I comment out the bindFactory and use the commented-out bind. Am I missing something in terms of the Factory implementation? The exception seems to happen even before the RepositoryFactory constructor is hit. I need the factory since I have some other initialization to do on the OracleRepository instance.
The only way I was able to reproduce the problem (with your incomplete information - i.e. missing injection point) was to try and inject
OracleRepositoryinstead ofRepository. I don't have the exact reason why the injection fails, but I guess it's because you're bindingRepositoryand notOracleRepository. If this is the problem, the simplest fix would be to bind the factory toOracleRepositoryor instead, simply injectRepository.For injection of
Repository, if you want to qualify different implementations you can do so by chainingnamedorqaulifiedByto the binding, as in the example below (where I usednamedand annotate the injection point with@Named).In the example I used the Jersey Test Framework
Here is the complete test. You can change the
@Namedbetween"Sql"and"Oracle"to see the difference.If you still have a problem, please post a complete single class test case like I have above that demonstrates the problem.