AssistedInject fails with optimized providers in edge cases
- Dominant language
- Java
- Stars
- 12.7k
- Forks
- 1.7k
- Avg merge
- 11m
- Merged PRs (30d)
- 2
Description
_From [sberlin](https://code.google.com/u/sberlin/) on May 24, 2011 11:40:18_
Normally, FactoryProvider2 would expect that the parent inject is constructing 'Object3' here, but Guice will recognize it has a dependency on something only the child can provide, so will fall back into adding the JIT binding for 'Object3' in the child injector. The rest of the FactoryProvider2 didn't expect this, and fails (visible with the "this should never happen").
A fix may be to inspect the JIT bindings of the child injector for dependencies that could invalidate the optimization. (If any child JIT binding exists, it has to be because it depends on an `@`Assisted param, which means they're tainted too, and all classes need to be analyzed for Provider<..> dependencies on them, and they need to be analyzed for Provider<..> dependencies of other tainted things.)
Test-code
-----
public class GuiceErrorTest extends TestCase {
`@`Inject
Object1Factory object1Factory;
public void testInjectionFailure() throws Exception {
Guice.createInjector(new Module()).injectMembers(this);
object1Factory.create(1).run();
}
public static class Module extends AbstractModule {
`@`Override
protected void configure() {
install(new FactoryModuleBuilder().build(Object1Factory.class));
install(new FactoryModuleBuilder().build(Object2Factory.class));
}
}
public interface Object1Factory {
Object1 create(`@`Assisted("a1") long a);
}
public static class Object1{
private final Object2Factory object2Factory;
private final long a;
`@`Inject
public Object1(`@`Assisted("a1") long a, Object2Factory object2Factory) {
this.a = a;
this.object2Factory = object2Factory;
}
public void run() throws Exception {
object2Factory.create(a).run();
}
}
public interface Object2Factory {
Object2 create(`@`Assisted("a1") long a);
}
public static class Object2 {
Provider<Object3> object3Provider;
`@`Inject
public Object2(Provider<Object3> object3Provider) {
this.object3Provider = object3Provider;
}
public void run() {
object3Provider.get(); // This will fail with an IllegalStateException
}
}
/*
* Instantiation of this Object fails at runtime:
* Cannot use optimized `@`Assisted provider outside the scope of the constructor.
*/
public static class Object3 {
`@`Inject
public Object3(`@`Assisted("a1") long a) {
}
}
}
_Original issue: http://code.google.com/p/google-guice/issues/detail?id=632_
Contributor guide
Assessment
This issue has not been assessed yet.