Reputation: 327
I'm trying to inject different versions of the same generic type, so far with no luck. The bindings that I do in the AbstractModule implementation are:
bind(new TypeLiteral<ConcurrentHashMap<String, Integer>>() {
}).annotatedWith(Names.named("name0")).toProvider(
ConcurrentHashMap::new).in(Singleton.class);
bind(new TypeLiteral<ConcurrentHashMap<String, Long>>() {
}).annotatedWith(Names.named("name1")).toProvider(
ConcurrentHashMap::new).in(Singleton.class);
bind(new TypeLiteral<ConcurrentHashMap<String, Boolean>>() {
}).annotatedWith(Names.named("name2")).toProvider(
ConcurrentHashMap::new).in(Singleton.class);
bind(new TypeLiteral<ConcurrentHashMap<String, Short>>() {
}).annotatedWith(Names.named("name3")).toProvider(
ConcurrentHashMap::new).in(Singleton.class);
I tried injecting them by simply using:
@Inject @Named("name0") ConcurrentHashMap<String, Integer>;
and so on. However, I get the following error:
1) Unable to create binding for
java.util.concurrent.ConcurrentHashMap<java.lang.String, java.lang.Integer>
annotated with @com.google.inject.name.Named(value=name0). It was already configured on one or more child injectors or private modules
What am I doing wrong? Thanks!
Upvotes: 2
Views: 1525
Reputation: 327
I found that the problem is with the injector itself. When I use the "Regular" Guice injector (by calling Guice.createInjector(new MyModule())
everything works fine. However, I've been using the netflix governator injector (by calling LifecycleInjector.builder().withModules(new MyModule()).build().createInjector()
), which seems to be causing the problem.
Upvotes: 2
Reputation: 95614
The code is fine, and the error message is pretty clear: Check your child injectors and your private modules for any other bindings to @Named("name0") ConcurrentHashMap<String, Integer>
. Guice is very careful not to allow bindings for the same key in the same injector, even if the bindings are inaccessible directly from the parent injector due to child injectors or private modules.
You might also consider switching toProvider
syntax for
bind(new TypeLiteral<ConcurrentHashMap<String, Integer>>() {
}).annotatedWith(Names.named("name0")).toProvider(
ConcurrentHashMap::new).in(Singleton.class);
to the simpler use of to
:
bind(new TypeLiteral<ConcurrentHashMap<String, Integer>>() {})
.annotatedWith(Names.named("name0"))
.to(ConcurrentHashMap.class)
.in(Singleton.class);
...partially because it's more typical of Guice usage, and partially because it may allow Guice to be more permissive with duplicate bindings. (Guice might have a hard time detecting duplicates through the Java 8 translation from ConcurrentHashMap::new
to Provider<ConcurrentHashMap>
.) Diagnosing the duplicate binding is probably a better idea, though.
Upvotes: 2