Duplicate binding error without any annotation inside private module
- Dominant language
- Java
- Stars
- 12.7k
- Forks
- 1.7k
- Avg merge
- 11m
- Merged PRs (30d)
- 2
Description
I stumbled across a weird problem when binding of the same class but with an annotation is available in a parent injector and is bound the same class without an annotation inside a submodule.
I could create a minimal reproducer that shows the problem. I suspect that it's a bug but I could have just missed something. Hopefully someone can shed light onto this problem.
This doesn't work:
```
@Test
public void withoutAnnotation() {
Key key = Key.get(B.class, Names.named("b"));
Injector injector = Guice.createInjector(new AbstractModule() {
@Override protected void configure() {
bind(key).to(B.class).in(Singleton.class); // <-- error says that B is already bound here
PrivateBinder childBinder = binder().newPrivateBinder();
childBinder.bind(Key.get(B.class)).to(key); // <-- and this would be the duplicate binding (no annotation!)
childBinder.bind(A.class);
childBinder.expose(A.class);
}
});
injector.getInstance(A.class);
}
public static class A {
@Inject
public A(B b) {}
}
public static class B {}
```
The error I get is:
```
Unable to create binding for com.test.GuiceTest$B. It was already configured on one or more child injectors or private modules bound at com.test.GuiceTest$1.configure(GuiceTest.java:26)
If it was in a PrivateModule, did you forget to expose the binding?
at com.test.GuiceTest$1.configure(GuiceTest.java:24)
```
If I add an annotation to `B` in `A`'s constructor and, of course, at the binding too then everything works as I expect.
```
@Test
public void withAnnotation() {
Key key = Key.get(B.class, Names.named("b"));
Injector injector = Guice.createInjector(new AbstractModule() {
@Override protected void configure() {
bind(key).to(B.class).in(Singleton.class);
PrivateBinder childBinder = binder().newPrivateBinder();
childBinder.bind(Key.get(B.class, Names.named("c"))).to(key); // <-- just added an annotation
childBinder.bind(A.class);
childBinder.expose(A.class);
}
});
injector.getInstance(A.class);
}
public static class A {
@Inject
public A(@Named("c") B b) {} // <-- just added an annotation here too
}
public static class B {}
```
In the former case the binding of `B` without an annotation is unique too but doesn't work. So I need to add an annotation to `A`'s constructor just to make this case work. Seems kind of odd to me.
Help appreciated. Thanks!
Contributor guide
Assessment
This issue has not been assessed yet.