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:
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:
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:
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?
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.