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
OracleRepository
instead ofRepository
. I don't have the exact reason why the injection fails, but I guess it's because you're bindingRepository
and notOracleRepository
. If this is the problem, the simplest fix would be to bind the factory toOracleRepository
or instead, simply injectRepository
.For injection of
Repository
, if you want to qualify different implementations you can do so by chainingnamed
orqaulifiedBy
to the binding, as in the example below (where I usednamed
and annotate the injection point with@Named
).In the example I used the Jersey Test Framework
Here is the complete test. You can change the
@Named
between"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.