google / dagger

A fast dependency injector for Android and Java.
https://dagger.dev
Apache License 2.0
17.45k stars 2.02k forks source link

java.lang.NoClassDefFoundError: Failed resolution of: Lcom/amazon/device/messaging/ADMMessageHandlerBase; #1861

Closed mariuspena closed 4 years ago

mariuspena commented 4 years ago

Scenario: dagger2 = '2.23.2' version / latest android studio / latest gradle plugin .. I am adding the amazon device messaging jar as a compileOnly. If you are curious this is the documentation for it: https://developer.amazon.com/docs/adm/set-up.html

Of course you should include as a service in the manifest these classes: ADMMessageHandlerBase (I extend this and name it V1 because is for older devices) and ADMMessageHandlerJobBase (I extend this and name it V2 because is for newer devices).

Of course these classes are not always available when I run the app on different devices.

My dagger configuration has one AmazonModule with some classes that extend the ones above from the amazon sdk and where I try to inject my stuff.

@Module
public abstract class AmazonBindingModule {

    @ContributesAndroidInjector
    abstract AmazonMessageHandlerV1 bindAmazonMessageHandlerV1();

    @ContributesAndroidInjector
    abstract AmazonMessageHandlerV2 bindAmazonMessageHandlerV2();

    @ContributesAndroidInjector
    abstract AmazonMessageHandler bindAmazonMessageHandler();

}

But since the amazon classes are not always available I get the error from the title of this issue.

So my questions is: how to deal with classes that are not available at runtime but are referenced in the dagger configuration (based on a compileOnly argument)

mariuspena commented 4 years ago

I included the error also: --------- beginning of crash 05-27 15:09:10.037 1150-1150/my.testproject E/AndroidRuntime: FATAL EXCEPTION: main Process: my.testproject, PID: 1150 java.lang.NoClassDefFoundError: Failed resolution of: Lmy/testproject/util/notifications/AmazonMessageHandlerV2; at my.testproject.di.DaggerAppComponent.getMapOfClassOfAndProviderOfAndroidInjectorFactoryOf(DaggerAppComponent.java:364) at my.testproject.di.DaggerAppComponent.getDispatchingAndroidInjectorOfActivity(DaggerAppComponent.java:367) at my.testproject.di.DaggerAppComponent.injectMyTestprojectAppApp(DaggerAppComponent.java:728) at my.testproject.di.DaggerAppComponent.inject(DaggerAppComponent.java:725) at my.testproject.MyTestprojectAppApp.onCreate(MyTestprojectAppApp.java:98) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1015) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4774) at android.app.ActivityThread.access$1500(ActivityThread.java:160) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1382) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5491) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:984) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) Caused by: java.lang.ClassNotFoundException: Didn't find class "my.testproject.util.notifications.AmazonMessageHandlerV2" on path: DexPathList[[zip file "/data/app/my.testproject-1/base.apk", zip file "/system/priv-app/DeviceMessagingAndroidSDK/DeviceMessagingAndroidSDK.apk", zip file "/system/priv-app/MetricsApi/MetricsApi.apk", zip file "/system/priv-app/com.amazon.dp.logger/com.amazon.dp.logger.apk"],nativeLibraryDirectories=[/data/app/my.testproject-1/lib/arm, /vendor/lib, /system/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:511) at java.lang.ClassLoader.loadClass(ClassLoader.java:469) at my.testproject.di.DaggerAppComponent.getMapOfClassOfAndProviderOfAndroidInjectorFactoryOf(DaggerAppComponent.java:364)  at my.testproject.di.DaggerAppComponent.getDispatchingAndroidInjectorOfActivity(DaggerAppComponent.java:367)  at my.testproject.di.DaggerAppComponent.injectMyTestprojectAppApp(DaggerAppComponent.java:728)  at my.testproject.di.DaggerAppComponent.inject(DaggerAppComponent.java:725)  at my.testproject.MyTestprojectAppApp.onCreate(MyTestprojectAppApp.java:98)  at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1015)  at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4774)  at android.app.ActivityThread.access$1500(ActivityThread.java:160)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1382)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:135)  at android.app.ActivityThread.main(ActivityThread.java:5491)  at java.lang.reflect.Method.invoke(Native Method)  at java.lang.reflect.Method.invoke(Method.java:372)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:984)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)  Suppressed: java.lang.NoClassDefFoundError: my.testproject.util.notifications.AmazonMessageHandlerV2 at dalvik.system.DexFile.defineClassNative(Native Method) at dalvik.system.DexFile.defineClass(DexFile.java:226) at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:219) at dalvik.system.DexPathList.findClass(DexPathList.java:321) at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:54) ... 18 more Suppressed: java.lang.ClassNotFoundException: my.testproject.util.notifications.AmazonMessageHandlerV2 at java.lang.Class.classForName(Native Method) at java.lang.BootClassLoader.findClass(ClassLoader.java:781) at java.lang.BootClassLoader.loadClass(ClassLoader.java:841) at java.lang.ClassLoader.loadClass(ClassLoader.java:504) ... 17 more Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available 05-27 15:09:10.037 1150-1150/my.testproject I/AndroidRuntime: To Report FATAL to activityManagerService 05-27 15:09:10.201 1150-1150/my.testproject I/AndroidRuntime: Finished reporting FATAL to activityManagerService 05-27 15:09:10.201 1150-1150/my.testproject I/Process: Sending signal. PID: 1150 SIG: 9

Chang-Eric commented 4 years ago

I don't think this is something Dagger really supports. DispatchingAndroidInjector uses Class keys which is why this is failing, but even if that weren't the case I'm not sure that we are yet willing to guarantee that missing classes at runtime are going to run properly. We avoid class loading as much as possible of course (especially with fastInit mode), but it isn't a hard guarantee.

You likely can't use @ContriubtesAndroidInjector and will need to use some form of indirection to hide the missing classes from Dagger. Alternatively, you could make different components and builds for the different devices.

mariuspena commented 4 years ago

thank you!