Skip to content

MISSING_CONSTRUCTOR

Googler edited this page Mar 6, 2024 · 3 revisions

MISSING_CONSTRUCTOR

Summary

Guice will throw a MISSING_CONSTRUCTOR error when it can't find an injectable constructor to use to create the requested objects.

What is an "injectable" constructor?

See @Inject constructor documentation.

Common Causes

If the class you are trying to inject is already commonly used and the below causes are therefore unlikely, it could be that the MISSING_CONSTRUCTOR error is a red herring for a failure to correctly install a module that provides the Guice key in the production code or in tests. See MISSING_IMPLEMENTATION for more information.

Missing no-arg constructor {.missing-no-arg}

This usually happens when a class is not designed to work with Guice and has constructors that take one or more arguments but not annotated with @Inject.

Example:

public final class LegacyFoo {
  LegacyFoo(Bar bar) {
    ...
  }
}

There are two ways to fix the MISSING_CONSTRUCTOR error in this case:

  • Annotate the constructor with @Inject if possible

    public final class LegacyFoo {
      @Inject
      LegacyFoo(Bar bar) {
        ...
      }
    }
  • Add an explicit binding for LegacyFoo so Guice doesn't rely on JIT for LegacyFoo. The recommended way to do this is to add a Provider method for LegacyFoo:

    public final class LegacyFooModule extends AbstractModule {
      @Provides
      LegacyFoo provideLegacyFoo(Bar bar) {
        return new LegacyFoo(bar);
      }
    }

Note: both these example fixes assume that there is a binding for Bar. If Guice didn't know how to construct Bar objects, you would need to add a binding for Bar as well, otherwise you may get a MISSING_IMPLEMENTATION error when injecting Bar.

Class has a no-arg constructor

If you get a MISSING_CONSTRUCTOR error despite the class having a no-arg constructor, then it's likely that the injector this error is thrown from has opted in to require @Inject constructors or the constructor is private.

In addition to the fixes suggested above for the missing no-arg constructor case, you can also:

  • Opt-out of @Inject constructor requirement by removing the call to binder().requireAtInjectOnConstructors() (or uninstall Modules.requireAtInjectOnConstructorsModule()). However, we recommend that all Guice users to opt-in this requirement to make it explicit when a constructor is intended for Guice to use.
  • If the constructor is private, consider making it package private or public if it makes sense to change the visibility of the constructor.
Clone this wiki locally