google / dagger

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

Consuming a library module compatible with hilt and dagger(optional inject) in an @HiltAndroidApp using dagger gets ClassCastException #3416

Open andwhysoft opened 2 years ago

andwhysoft commented 2 years ago

I have a library module which is utilizing the @OptionalInject on the @AndroidEntryPoint classes with hilt and dagger modules setup to be compatible with both.

The consuming app was originally utilizing dagger which consumed the library properly through dagger. Now the consuming app has migrated over to hilt, however we still would like the library to be utilized through dagger, the reason being to keep the encapsulation of the library separate. We are seeing the below class cast exception when hilt is being utilized in the app.

2022-06-02 13:15:44.692 12227-12227/com.example.app.dev E/outlook.crash: App crashing with the following unhandled exception
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.app.dev/com.example.sdk.ui.Activity}: java.lang.ClassCastException: com.example.app.c3$b cannot be cast to com.example.sdk.ui.Activity_GeneratedInjector
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3430)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)
        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:2199)
        at android.os.Handler.dispatchMessage(Handler.java:112)
        at android.os.Looper.loop(Looper.java:216)
        at android.app.ActivityThread.main(ActivityThread.java:7625)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
     Caused by: java.lang.ClassCastException: com.example.app.c3$b cannot be cast to com.example.sdk.ui.Activity_GeneratedInjector
        at com.example.sdk.ui.Hilt_Activity.inject(SourceFile:86)
        at com.example.sdk.ui.Hilt_Activity$1.onContextAvailable(SourceFile:41)
        at e.a.c(SourceFile:99)
        at androidx.activity.SomeActivity.onSomeCreate(SourceFile:320)
        at androidx.fragment.app.e.onSomeCreate(SourceFile:249)
        at com.example.sdk.ui.Activity.onSomeCreate(SourceFile:46)
        at com.example.x.app.offline.OfflineActivityBehavior.onCreate(SourceFile:90)
        at com.example.x.app.SomeActivity.onCreate(SourceFile:77)
        at android.app.Activity.performCreate(Activity.java:7458)
        at android.app.Activity.performCreate(Activity.java:7448)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86) 
        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:2199) 
        at android.os.Handler.dispatchMessage(Handler.java:112) 
        at android.os.Looper.loop(Looper.java:216) 
        at android.app.ActivityThread.main(ActivityThread.java:7625) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987) 
2022-06-02 13:15:44.693 1231-6192/? E/ActivityManager: The same pid with last one, do not add dropbox and clear mLastCrashedPid. mLastAppCrashedPid==12227

We are suspecting @OptionalInject potentially doesn't work where the application utilizes hilt, but we are trying to consuming the library as dagger to keep the encapsulation of the library separate. It seems that there will be a check against the parent ojbect that check if it uses hilt and will then default to hilt, which will run into this class cast exception. Is there a way to resolve this issue so that the library is used as dagger even though the library also supports hilt? or would we have to remove hilt from the library to maintain the encapsulation through dagger usage?

I have tried the enableExperimentalClasspathAggregation and enableAggregatingTask in some issue I have found https://github.com/google/dagger/issues/3004, but those don't seem to be exactly pertaining to this issue.

bcorso commented 2 years ago

This sounds similar to https://github.com/google/dagger/issues/3386. If you're optimizing your sdk r8 is likely removing Hilt's entry points.

andwhysoft commented 2 years ago

Unfortunately r8/proguard isn't related to the issue with the sdk. I will check the app's optimization to see if the issues is from that side maybe.