No implementation was bound - Java Guice

匿名 (未验证) 提交于 2019-12-03 08:52:47

问题:

Novice here trying to use a dummy Java Facebook app that uses Guice to inject a database dependency into the Facebook factory but continue to have Guice error out telling me:

### No implementation for com.example.storage.Db annotated with @com.example.storage.annotations.SystemDb() was bound while locating com.example.storage.Db annotated with @com.example.storage.annotations.SystemDb() for parameter 0 at com.example.facebook.client.exceptions.FacebookExceptionHandlerDb at com.example.facebook.client.guice.FacebookClientModule.configure

### Could not find a suitable constructor in com.example.facebook.statsd.StatsdClient. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private. at com.example.facebook.statsd.StatsdClient.class while locating com.example.facebook.statsd.StatsdClient for parameter 1 at com.example.facebook.client.exceptions.FacebookExceptionHandlerDb. com.example.facebook.client.guice.FacebookClientModule.configure

Code for app:

app.java

package com.example.facebook;  import com.google.inject.Guice; import com.restfb.Connection; import com.restfb.types.Post; import com.example.facebook.client.FacebookClientFactory; import com.example.facebook.client.RobustFacebookClient; import com.example.facebook.client.guice.FacebookClientModule; import com.example.facebook.statsd.StatsdClient;  public class App  {     public static void main ( String[] args ) {           final FacebookClientFactory facebookClientFactory =             Guice.createInjector(new FacebookClientModule()).getInstance(FacebookClientFactory.class);           //error from line above           final RobustFacebookClient robustFacebookClient =             facebookClientFactory.create("accessToken");           //more ...     } 

The resulting error points me to the FacebookClientModule binding:

FacebookClientModule.java

public class FacebookClientModule extends AbstractModule {     bind(FacebookExceptionHandler.class).to(FacebookExceptionHandlerDb.class);     //error resulting from the failed binding on the FacebookExceptionHandlerDB class      install(new FactoryModuleBuilder()             .implement(FacebookClient.class, RobustFacebookClient.class)             .build(FacebookClientFactory.class));     } 

}

Where inside the FacebookExceptionHandleDB class the constructor has the injection:

FacebookExceptionHandlerDB.java

public class FacebookExceptionHandlerDb implements FacebookExceptionHandler {      // list of class String variables ...      private final FacebookErrorParser parser;     private final Db db;     private StatsdClient statsd;      @Inject     public FacebookExceptionHandlerDb(@SystemDb Db db, StatsdClient statsd,    FacebookErrorParser parser) {         this.db = db;         this.statsd = statsd;         this.parser = parser;     } } 

From what I can gleam, the dependency injection for parameters zero and one, db and statsD respectively, is failing. Could someone point out where or what in the app code is missing?

回答1:

At first glance it seems like your missing the bindings for the Db annotated dependency and the StatsdClient.

You'll need to provide the missing bindings to your module like so

bind(Db.class).annotatedWith(SystemDb.class).to(DbImplOfSomeSort.class); bind(StatsdClient.class).to(StatsdClientImplOfSomeSort.class); 

Guice is able to automatically inject Concrete Class with either a public no argument constructor or a constructor with @Inject without any specific defined binding in your module but when it comes to Interfaces you have to define the necessary bindings.

Here Db.class and StatsdClient.class are interfaces which you need to bind to specific implementation.



回答2:

Not the source of the issue in this particular case, but I ran across this issue when I had my implementation and interface classes backwards:

public class MyModule extends AbstractModule {     @Override     public void configure() {         bind(MyClassImpl.class).to(MyInterface.class);     } } 

Should have been:

bind(MyInterface.class).to(MyClassImpl.class); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!