1
votes

I have a interface as

public interface ConfFileLoader {

    public Map<String, Object> getResultMap() throws SecurityException, IOException;
}

and a class that imlements it as

public class ConfYamlLoader implements ConfFileLoader{

    @Override
    public Map<String, Object> getResultMap() throws SecurityException, IOException {

    }

}

and has a injector class as

public class AppInjector extends AbstractModule {
    @Override
    public void configure() {
        bind(ConfFileLoader.class).to(ConfYamlLoader.class);
    }
}

Now the problem is i have a class as

public class TI {


    @Inject
    private ConfFileLoader confFileLoader;


    public void test(){
        System.out.println("yeah tesrintY>>>>>>>>>>>>>>>>>>>"+confFileLoader);
    }

}

and it gives exception as

Exception in thread "main" com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for com.exzeo.conf.ConfFileLoader was bound.
  while locating com.exzeo.conf.ConfFileLoader
    for field at com.exzeo.automate.HCPCI.TI.confFileLoader(TI.java:10)
  while locating com.exzeo.automate.HCPCI.TI

but when i do @ConfYamlLoader it works fine as

public class TI {


    @Inject
    private ConfYamlLoader confFileLoader;


    public void test(){
        System.out.println("yeah tesrintY>>>>>>>>>>>>>>>>>>>"+confFileLoader);
    }

}

This above class works fine

So on investigation I found when I add @implemetedby on ConfFileLoader it works fine as

@ImplementedBy(ConfYamlLoader.class)
public interface ConfFileLoader {

    public Map<String, Object> getResultMap() throws SecurityException, IOException;
}

I can't understand this behaviour that why i need to do @ImplementedBy if I am already binding it in binding module. As I per my understanding @implementedby is equavlane to bind().

Let me know if I am missing anything and I am using guice version 3

1
The only reason this can happen is that you're not using your module at all. Check once more that you indeed are passing AppInjector instance to Guice.createInjector(). - Vladimir Matveev
Injector injector = Guice.createInjector(new AppInjector()); I am doing this @VladimirMatveev - Dhruv Pal
Sorry, but I couldn't reproduce your problem. Please see this gist. It contains exactly the code you have provided and a small piece of glue code in Main. It works perfectly for me, printing guicex.ConfYamlLoader@5dbc26ee when test() method is called. - Vladimir Matveev
@VladimirMatveev Sorry I didn't mention something important. I am usin testng To run a test class and in that class I am injecting ConFileLoader. I am uisng testng as TestNG tng = new TestNG(); tng.setXmlSuites(xmlSuiteBuilder.getSuites()); tng.run(); xml suite builder give details of Test Class - Dhruv Pal

1 Answers

1
votes

Your line

bind(ConfFileLoader.class).to(ConfYamlLoader.class);

means "whenever you're going to inject a value of type ConfFileLoader, instead inject a value of type ConfYamlLoader and use that".

But you still need to bind ConfYamlLoader somehow so that it can be injected.

If it has an @Inject-annotated constructor, or a public no-args constructor (unless you've called binder.requireAtInjectOnConstructors() somewhere), then Guice will use that.

Otherwise, you'll need to bind a Provider<ConfYamlLoader> somehow, either by using a @Provides ConfYamlLoader method or bind(ConfYamlLoader).toProvider(...) or .toInstance(...).