Jens Moser
Jens Moser

Reputation: 163

Toothpick NoFactoryFoundException

The app I'm working on is crashing in production and users are reporting the below stack trace. The problem is that I cannot reproduce it myself.

Caused by: toothpick.registries.NoFactoryFoundException: 
  at toothpick.registries.FactoryRegistryLocator.getFactoryUsingRegistries (FactoryRegistryLocator.java:49)
  at toothpick.configuration.ReflectionOffConfiguration.getFactory (ReflectionOffConfiguration.java:11)
  at toothpick.configuration.Configuration.getFactory (Configuration.java:113)
  at toothpick.registries.FactoryRegistryLocator.getFactory (FactoryRegistryLocator.java:38)
  at toothpick.ScopeImpl.lookupProvider (ScopeImpl.java:329)
  at toothpick.ScopeImpl.getInstance (ScopeImpl.java:58)
  at toothpick.ScopeImpl.getInstance (ScopeImpl.java:49)
  at my.package.name.activity.MainActivity$$MemberInjector.inject (MainActivity$$MemberInjector.java:13)
  at my.package.name.activity.MainActivity$$MemberInjector.inject (MainActivity$$MemberInjector.java:10)
  at toothpick.InjectorImpl.inject (InjectorImpl.java:25)
  at toothpick.Toothpick.inject (Toothpick.java:149)
  at my.package.name.BaseActivity.injectInScopes (BaseActivity.java:17)
  at my.package.name.activity.MainActivity.onCreate (MainActivity.java:120)
  at android.app.Activity.performCreate (Activity.java:6876)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1135)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3206)

It's crashing in different Activities at different times for different users. The missing Factory is present (at least for me) as can be seen below.

public final class MainActivity$$MemberInjector implements MemberInjector<MainActivity> {
  @Override
  public void inject(MainActivity target, Scope scope) {
    target.myLogger = scope.getInstance(MyLogger.class);
    ...
  }
}

The missing factory:

public final class MyLoggerImpl$$Factory implements Factory<MyLoggerImpl> {
  @Override
  public MyLoggerImpl createInstance(Scope scope) {
    scope = getTargetScope(scope);
    RestApi param1 = scope.getInstance(RestApi.class);
    Scope param2 = scope.getInstance(Scope.class);
    MyLoggerImpl myLoggerImpl = new MyLoggerImpl(param1, param2);
    return myLoggerImpl;
  }

  @Override
  public Scope getTargetScope(Scope scope) {
    return scope;
  }

  @Override
  public boolean hasScopeAnnotation() {
    return false;
  }

  @Override
  public boolean hasProvidesSingletonInScopeAnnotation() {
    return false;
  }
}

Module:

bind(MyLogger.class).to(MyLoggerImpl.class).singletonInScope();

This occurs when using either Toothpick reflection or reflection-free configuration. Any ideas on why I get this exception?

Upvotes: 1

Views: 1140

Answers (1)

Jens Moser
Jens Moser

Reputation: 163

I figured this one out. I was using Toothpick the wrong way and my scope wasn't recreated when the application had been in the background for sometime and the user reentered the app.

Note to self: Android applications and activities can be killed by Android when the app is in the background. Make sure that the app and Toothpick can recover safely from that. Keep the dependency injection model simple.

Upvotes: 2

Related Questions