Guice method injection error : "Unable to create binding for <class>. It was already configured on one or more child injectors or private modules"

Viewed 3022

I have the following class wherein I need method injection using Guice.

@Singleton
public class A {

    private final Injector injector;

    @Inject
    public A(Injector injector) {
       this.injector = injector;
    }

    public void method1() {
        ...
        final XInterface x = this.injector.getInstance(Key.get(XInterface.class, Names.named("provideX")));
        ...
    }
}

And the module contains the following provides method:

public class MyModule extends AbstractModule {

    @Override void configure() {
        // no binding and scope for class A
    }

    @Provides
    @Named("provideX")
    public XInterface provide(@Named("isTest") boolean isTest, X x, XMock xMock) {
        return isTest ? xMock : x;
    }
}

Where isTest has a provider in the same module and can be ignored for this discussion.

Now, this injection in class A gives me the following error:

Unable to create binding for `A`. It was already configured on one or more child injectors or private modules. If it was in a PrivateModule, did you forget to expose the binding?

and the rest of the stacktrace isn't very helpful.

After digging around for a while and trying out a few things, I found that just defining a Singleton scope for class A in the MyModule.configure() like so : bind(A.class).in(Singleton.class); and removing the existing @Singleton annotation on the class A solved the error. Now my question is two fold:

  • What caused the error in my first implementation?
  • What is the difference between defining a singleton scope in the module and annotating a class with singleton scope and why did that solve the problem?

Thanks in advance!

0 Answers
Related