toothpick.locators.NoFactoryFoundException in Signed APK [2.1.0]
See original GitHub issueHi Together
I got an issue when building the apk and trying to run it.
I know others had such problems as well but none of those issues sadly seem to apply to me. 😕
I am creating an Android Library and so far everything worked fine when running it through Android Studio in a demo app. However once I create the signed APK some things seem to go a bit awry. Suddenly Toothpick complains that it cannot locate certain Member Injectors. Even though I am binding & injecting the instances myself.
Am I missing something during the build phase which I need to change?
Information
I am sry I know its a lot. But I think something in here is contributing to the issue but I cant figure out what it is.
Here I am binding all required instances to the Scope FeedbackSingleton.class
@SuppressWarnings("Injectable")
public class FeedbackSetupService implements IFeedbackExitPoint {
...
@Inject
IFeedbackExitPoint feedbackExitPoint;
...
public void open(final Activity fromActivity) {
Scope feedbackScope = Toothpick.openScope(FeedbackSingleton.class);
feedbackScope.installModules(new Module() {{
bind(Application.class).toInstance(fromActivity.getApplication());
bind(NetworkService.class).toInstance(new NetworkService());
}});
feedbackScope.installModules(new Module() {{
bind(FeedbackRoomDatabase.class).toProviderInstance(new FeedbackRoomDatabaseProvider());
final AssetsServiceProvider assetsServiceProviderInstance = new AssetsServiceProvider();
bind(AssetsServiceProvider.class).toInstance(assetsServiceProviderInstance);
bind(AssetsService.class).toProviderInstance(assetsServiceProviderInstance);
bind(FileService.class).toProviderInstance(new FileServiceProvider());
}});
// Here I changed the way I create the module to see if that changes things but it doesnt
Module tpModStage3 = new Module();
tpModStage3.bind(FeedbackRepository.class).toInstance(new FeedbackRepository());
tpModStage3.bind(FeedbackConfigurationService.class).toInstance(new FeedbackConfigurationService());
tpModStage3.bind(IFeedbackExitPoint.class).toInstance(this);
feedbackScope.installModules(tpModStage3);
// Interestingly enough TP does not complain here about missing Injector for the same class
// That is `IFeedbackExitPoint.java`
Toothpick.inject(this, feedbackScope);
}
...
}
This activity fails to inject suddenly in the signed APK.
public class TextSideActivity extends BaseActivity {
...
// This one fails to inject
@Inject
IFeedbackExitPoint feedbackExitPoint;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeatureCompat(Window.FEATURE_NO_TITLE);
contentView = getLayoutInflater().inflate(R.layout.textside_activity, null);
setContentView(contentView); // Cannot be done by ButterKnife - only calls which can be done by findViewById()
Toothpick.inject(this, Toothpick.openScope(FeedbackSingleton.class));
ButterKnife.bind(this);
init();
initValueListeners();
}
...
}
Information about IFeedbackExitPoint
IFeedbackExitPoint#close takes care of closing the TP scope as well as making sure to tear down any other ressources used.
public interface IFeedbackExitPoint {
void close();
}
This is the stacktrace which I am suddenly getting in the singed APK.
2019-08-07 12:03:07.338 17155-17155/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: ch.fhnw.edu.fcp.feedbackcommprocess, PID: 17155
java.lang.RuntimeException: Unable to start activity ComponentInfo{ch.fhnw.edu.fcp.feedbackcommprocess/ch.fhnw.edu.fcp.postcard.activity.TextSideActivity}: toothpick.locators.NoFactoryFoundException: No factory could be found for class ch.fhnw.edu.fcp.postcard.IFeedbackExitPoint. Check that the class has either a @Inject annotated constructor or contains @Inject annotated members.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2919)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3054)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1814)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:280)
at android.app.ActivityThread.main(ActivityThread.java:6710)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: toothpick.locators.NoFactoryFoundException: No factory could be found for class ch.fhnw.edu.fcp.postcard.IFeedbackExitPoint. Check that the class has either a @Inject annotated constructor or contains @Inject annotated members.
at toothpick.locators.FactoryLocator.getFactory(FactoryLocator.java:21)
at toothpick.ScopeImpl.lookupProvider(ScopeImpl.java:329)
at toothpick.ScopeImpl.getInstance(ScopeImpl.java:58)
at toothpick.ScopeImpl.getInstance(ScopeImpl.java:49)
at ch.fhnw.edu.fcp.postcard.activity.TextSideActivity__MemberInjector.inject(TextSideActivity__MemberInjector.java:12)
at ch.fhnw.edu.fcp.postcard.activity.TextSideActivity__MemberInjector.inject(TextSideActivity__MemberInjector.java:9)
at toothpick.InjectorImpl.inject(InjectorImpl.java:23)
at toothpick.Toothpick.inject(Toothpick.java:163)
at ch.fhnw.edu.fcp.postcard.activity.TextSideActivity.onCreate(TextSideActivity.java:141)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2899)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3054)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1814)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:280)
at android.app.ActivityThread.main(ActivityThread.java:6710)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.ClassNotFoundException: ch.fhnw.edu.fcp.postcard.IFeedbackExitPoint__Factory
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:453)
at java.lang.Class.forName(Class.java:378)
at toothpick.locators.FactoryLocator.getFactory(FactoryLocator.java:18)
at toothpick.ScopeImpl.lookupProvider(ScopeImpl.java:329)
at toothpick.ScopeImpl.getInstance(ScopeImpl.java:58)
at toothpick.ScopeImpl.getInstance(ScopeImpl.java:49)
at ch.fhnw.edu.fcp.postcard.activity.TextSideActivity__MemberInjector.inject(TextSideActivity__MemberInjector.java:12)
at ch.fhnw.edu.fcp.postcard.activity.TextSideActivity__MemberInjector.inject(TextSideActivity__MemberInjector.java:9)
at toothpick.InjectorImpl.inject(InjectorImpl.java:23)
at toothpick.Toothpick.inject(Toothpick.java:163)
at ch.fhnw.edu.fcp.postcard.activity.TextSideActivity.onCreate(TextSideActivity.java:141)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2899)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3054)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1814)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:280)
at android.app.ActivityThread.main(ActivityThread.java:6710)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.ClassNotFoundException: Didn't find class "ch.fhnw.edu.fcp.postcard.IFeedbackExitPoint__Factory" on path: DexPathList[[zip file "/mnt/expand/0c815ad2-6acf-42db-ab64-6125c2e82827/app/ch.fhnw.edu.fcp.feedbackcommprocess-wjud-Zz1fbQxV8atrA5G5Q==/base.apk"],nativeLibraryDirectories=[/mnt/expand/0c815ad2-6acf-42db-ab64-6125c2e82827/app/ch.fhnw.edu.fcp.feedbackcommprocess-wjud-Zz1fbQxV8atrA5G5Q==/lib/arm64, /system/lib64, /vendor/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:453)
at java.lang.Class.forName(Class.java:378)
at toothpick.locators.FactoryLocator.getFactory(FactoryLocator.java:18)
at toothpick.ScopeImpl.lookupProvider(ScopeImpl.java:329)
at toothpick.ScopeImpl.getInstance(ScopeImpl.java:58)
at toothpick.ScopeImpl.getInstance(ScopeImpl.java:49)
at ch.fhnw.edu.fcp.postcard.activity.TextSideActivity__MemberInjector.inject(TextSideActivity__MemberInjector.java:12)
at ch.fhnw.edu.fcp.postcard.activity.TextSideActivity__MemberInjector.inject(TextSideActivity__MemberInjector.java:9)
at toothpick.InjectorImpl.inject(InjectorImpl.java:23)
at toothpick.Toothpick.inject(Toothpick.java:163)
at ch.fhnw.edu.fcp.postcard.activity.TextSideActivity.onCreate(TextSideActivity.java:141)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2899)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3054)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1814)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:280)
at android.app.ActivityThread.main(ActivityThread.java:6710)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Using gradle directly lint complains as well
.gradle/caches/modules-2/files-2.1/com.github.stephanenicolas.toothpick/toothpick-runtime/2.1.0/e4456493ef995a4e7c4a541a64106a5b4c78a685/toothpick-runtime-2.1.0.jar: Error: Invalid package reference in library; not included in Android: javax.inject. Referenced from toothpick.ScopeNode. [InvalidPackage]
App Gradle (Demo App)
apply plugin: 'com.android.application'
android {
android {
lintOptions {
// abortOnError false
// warning 'InvalidPackage'
}
}
signingConfigs {
release {
storeFile file('/home/lukaswillin/Clouds/OwnCloud/SwitchDrive/IP6/Sonstiges/apk-signing-keystore.jks')
storePassword '**********'
keyAlias = 'fhnwkey'
keyPassword '***********'
}
}
compileSdkVersion 28
defaultConfig {
applicationId "ch.fhnw.edu.fcp.feedbackcommprocess"
minSdkVersion 14
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
signingConfig signingConfigs.release
}
buildTypes {
release {
minifyEnabled false
useProguard false
debuggable = true
signingConfig signingConfigs.release
multiDexEnabled = true
}
debug {
signingConfig signingConfigs.debug
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation project(':feedbackpostcard')
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// View Injection / Butterknife
// Known Warning variantOutput.getProcessResources() is obsolete caused by the library version of butterknife
apply plugin: 'com.jakewharton.butterknife'
implementation 'com.jakewharton:butterknife:10.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
// Room components
// Alpha 4 has been chosen since Alpha 5 would break the build
implementation "androidx.room:room-runtime:2.1.0-alpha04"
annotationProcessor "androidx.room:room-compiler:2.1.0-alpha04"
androidTestImplementation "androidx.room:room-testing:2.1.0-alpha04"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.0.0"
// Joda DateTime Library
implementation 'joda-time:joda-time:2.10.2'
// Toothpick DI
implementation 'com.github.stephanenicolas.toothpick:toothpick-runtime:2.1.0'
annotationProcessor 'com.github.stephanenicolas.toothpick:toothpick-compiler:2.1.0'
testImplementation 'com.github.stephanenicolas.toothpick:toothpick-testing-junit5:2.1.0'
testImplementation 'org.mockito:mockito-core:2.28.2'
// CompletableFuture Backport
implementation 'net.sourceforge.streamsupport:android-retrofuture:1.7.1'
}
Library Module Gradle (Feedback)
apply plugin: 'com.android.library'
android {
android {
lintOptions {
// abortOnError false
// warning 'InvalidPackage'
}
}
signingConfigs {
release {
storeFile file('/home/lukaswillin/Clouds/OwnCloud/SwitchDrive/IP6/Sonstiges/apk-signing-keystore.jks')
storePassword '*************'
keyAlias = 'fhnwkey'
keyPassword '*************
}
}
compileSdkVersion 28
defaultConfig {
minSdkVersion 14
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
useProguard false
minifyEnabled false
debuggable = true
signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.debug
multiDexEnabled = true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
dataBinding {
enabled = true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.vectordrawable:vectordrawable:1.0.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// View Injection / Butterknife
// Known Warning variantOutput.getProcessResources() is obsolete caused by the library version of butterknife
apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'
implementation 'com.jakewharton:butterknife:10.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
// Room components
implementation "androidx.room:room-runtime:2.1.0-alpha04"
annotationProcessor "androidx.room:room-compiler:2.1.0-alpha04"
androidTestImplementation "androidx.room:room-testing:2.1.0-alpha04"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.0.0"
// Joda DateTime Library
implementation 'joda-time:joda-time:2.10.2'
// Toothpick DI
implementation 'com.github.stephanenicolas.toothpick:toothpick-runtime:2.1.0'
annotationProcessor 'com.github.stephanenicolas.toothpick:toothpick-compiler:2.1.0'
testImplementation 'com.github.stephanenicolas.toothpick:toothpick-testing-junit5:2.1.0'
testImplementation 'org.mockito:mockito-core:2.+'
// CompletableFuture Backport
implementation 'net.sourceforge.streamsupport:android-retrofuture:1.7.1'
// Phototeditor
implementation 'ja.burhanrashid52:photoeditor:0.4.0'
}
Issue Analytics
- State:
- Created 4 years ago
- Comments:14 (6 by maintainers)
Top GitHub Comments
Already did 😉 Thank you!
If it works when running in debug mode, and not in release mode, your problem probably comes from obfuscation. Then you would have a different stack trace too, not one starting as an issue from the activity…Do you obfuscate your apk and if so did you configure it to preserve TP classes and generated code? See the wiki on how to do it.
You can also dump a scope using toString and see what are the bindings available. It can help debug.