I was able to find out what the problem was. One of the private modules had a constructor-injected dependency to a concrete class which was logically part of another private module. But since implicit bindings are created for concrete classes, the other class from the other private module became accidentally part of the this private module.
Here a test to reproduce (also in http://pastebin.com/wt3YrkEx). The problem was that Foo had a direct dependency to Bar. The solution that I'll try is to create an interface for Bar, so that bindings are not created implicitly for it, and then expose Bar's interface from the other private module. import com.google.inject.*; import com.google.inject.name.Names; import org.junit.Test; import static org.junit.Assert.assertEquals; public class PrivateModuleBugTest { @Test public void private_modules_should_not_see_each_others_private_bindings() { Injector injector = Guice.createInjector(new FooModule(), new BarModule()); PrivateValue foo = injector.getInstance(Key.get(PrivateValue.class, Names.named("Foo"))); Bar bar = ((Foo) foo).bar; assertEquals("Foo", foo.getClass().getSimpleName()); assertEquals("Foo-private", foo.getPrivateValue()); assertEquals("Bar", bar.getClass().getSimpleName()); assertEquals("Bar-private", bar.getPrivateValue()); // actually returns "Foo-private" } } class FooModule extends PrivateModule { protected void configure() { bind(String.class).toInstance("Foo-private"); bind(PrivateValue.class).to(Foo.class); bind(PrivateValue.class).annotatedWith(Names.named("Foo")).to(Foo.class); expose(PrivateValue.class).annotatedWith(Names.named("Foo")); } } class BarModule extends PrivateModule { protected void configure() { bind(String.class).toInstance("Bar-private"); bind(PrivateValue.class).to(Bar.class); bind(PrivateValue.class).annotatedWith(Names.named("Bar")).to(Bar.class); expose(PrivateValue.class).annotatedWith(Names.named("Bar")); } } class Foo implements PrivateValue { private final String privateValue; public final Bar bar; @Inject public Foo(String privateValue, Bar bar) { // there is no warning about this dependency to Bar this.privateValue = privateValue; this.bar = bar; } public String getPrivateValue() { return privateValue; } } class Bar implements PrivateValue { private final String privateValue; @Inject public Bar(String privateValue) { this.privateValue = privateValue; } public String getPrivateValue() { return privateValue; } } interface PrivateValue { String getPrivateValue(); } -- You received this message because you are subscribed to the Google Groups "google-guice" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.
