Skip to content

MISSING_IMPLEMENTATION

Googler edited this page Feb 23, 2022 · 6 revisions

MISSING_IMPLEMENTATION

Summary

Guice will throw a MISSING_IMPLEMENTATION error when an application requests an object that Guice does not know how to create.

Common Causes

Missing or incorrect binding annotation

Make sure your code is requesting the correct Guice key. For example, if you have a module that provides @Production Database but your code is trying to inject Database then Guice will report a missing implementation error because it does not know how to construct Database, only @Production Database.

To fix this, update your code to inject the correct object.

Example:

// Given a module that binds `@Production Database`:
class DatabaseModule extends AbstractModule {
  @Provides
  @Production
  Database provideDatabase() {
    return new RealDatabase();
  }
}
// Incorrect
final class Foo {
  @Inject
  Foo(Database db) {
  }
}
// Correct
final class Foo {
  @Inject
  Foo(@Production Database db) {
  }
}

Missing module installation

If there is a module that provides the missing Guice key, make sure it is installed in the injector. If your application has multiple injectors, also check that the module is installed in the correct injector.

Example:

final class Foo {
  @Inject
  Foo(Database db) {
    ...
  }
}
final class MyServer {
  public static void main(String[] args) {
    // DatabaseModule tells Guice how to create instances of Database,
    // without it, Guice will throw MISSING_IMPLEMENTATION error so make sure
    // it is installed in the injector.
    Inject injector = Guice.createInjector(
        ...
        new DatabaseModule(),
        ...);
  }
}

MISSING_IMPLEMENTATION errors in tests

If your production code runs fine but you are getting MISSING_IMPLEMENTATION errors in one or more of your tests, then make sure you have set up the tests so the injectors created in the tests know how to create the missing binding.

Tests often create a different and smaller injector that only contains a subset of all the bindings that exist in a production injector. So you may run into MISSING_IMPLEMENTATION errors in your test if the test injector is missing bindings supplied by modules that are only installed in the production injector. You can fix this issue by installing the missing binding, using either the production implementation or a fake. Guice makes it easy to swap out dependencies for fake implementations or mocks.

TIP: BoundFields make it easy to bind fake implementations and mocks in tests.

Example:

// Given a class Foo that requires the @Production Database...
class Foo {
  @Inject
  Foo(@Production Database db) { ... }
}

// And a test helper module that binds the database to an in-memory instance
class TestDbModule {
  @Provides
  @Production
  Database provideDatabase() {
    return new InMemoryDatabase();

  }
}
final class FooTest {
  @Inject private Foo foo; // Foo requires the Database binding

  @Before
  public void setUp() {
    // This injector does not know how to construct Database
    Guice.createInjector().injectMembers(this);
  }

  @Test
  public void testMethod() {
    ...
  }
}
final class FooTest {
  @Inject private Foo foo; // Foo requires the Database binding

  @Before
  public void setUp() {
    // TestDbModule binds Database to an in-memory test database,
    // which Foo will use.
    Guice.createInjector(new TestDbModule()).injectMembers(this);
  }

  @Test
  public void testMethod() {
    ...
  }
}
Clone this wiki locally