Получение java.lang.ExceptionInInitializerError в приложении динамической доставки
У нас возникают сбои на некоторых конкретных устройствах в производстве - возникает это исключение:
Fatal Exception: java.lang.ExceptionInInitializerError
at com.road.mobile.home.viewmodel.DashboardViewModel.<init>(DashboardViewModel.java:25)
at com.road.mobile.home.viewmodel.DashboardViewModel$Factory.create(DashboardViewModel.java:32)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.road.mobile.home.fragment.DashboardFragment$dashboardViewModel$2.invoke(DashboardFragment.java:92)
at com.road.mobile.home.fragment.DashboardFragment$dashboardViewModel$2.invoke(DashboardFragment.java:80)
at kotlin.SynchronizedLazyImpl.getValue(SynchronizedLazyImpl.java:74)
at com.road.mobile.home.fragment.DashboardFragment.getDashboardViewModel(DashboardFragment.java)
at com.road.mobile.home.fragment.DashboardFragment.initFinancialToolsUi(DashboardFragment.java:218)
at com.road.mobile.home.fragment.DashboardFragment.initUI(DashboardFragment.java:159)
at com.road.mobile.home.fragment.DashboardFragment.onViewCreated(DashboardFragment.java:115)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:298)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1232)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1398)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1476)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1541)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2333)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2120)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2075)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1977)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2862)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2812)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at com.road.mobile.base.activity.BaseActivity.onStart(BaseActivity.java:116)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1228)
at android.app.Activity.performStart(Activity.java:5991)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2423)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2522)
at android.app.ActivityThread.access$800(ActivityThread.java:167)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1417)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5537)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:956)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:751)
Caused by java.lang.ClassNotFoundException: co.getroad.investment.InvestmentFeatureImpl$Provider
at java.lang.Class.classForName(Class.java)
at java.lang.Class.forName(Class.java:308)
at java.lang.Class.forName(Class.java:272)
at com.road.mobile.InvestmentFeature.<clinit>(InvestmentFeature.java:75)
at com.road.mobile.home.viewmodel.DashboardViewModel.<init>(DashboardViewModel.java:25)
at com.road.mobile.home.viewmodel.DashboardViewModel$Factory.create(DashboardViewModel.java:32)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.road.mobile.home.fragment.DashboardFragment$dashboardViewModel$2.invoke(DashboardFragment.java:92)
at com.road.mobile.home.fragment.DashboardFragment$dashboardViewModel$2.invoke(DashboardFragment.java:80)
at kotlin.SynchronizedLazyImpl.getValue(SynchronizedLazyImpl.java:74)
at com.road.mobile.home.fragment.DashboardFragment.getDashboardViewModel(DashboardFragment.java)
at com.road.mobile.home.fragment.DashboardFragment.initFinancialToolsUi(DashboardFragment.java:218)
at com.road.mobile.home.fragment.DashboardFragment.initUI(DashboardFragment.java:159)
at com.road.mobile.home.fragment.DashboardFragment.onViewCreated(DashboardFragment.java:115)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:298)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1232)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1398)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1476)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1541)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2333)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2120)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2075)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1977)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2862)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2812)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at com.road.mobile.base.activity.BaseActivity.onStart(BaseActivity.java:116)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1228)
at android.app.Activity.performStart(Activity.java:5991)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2423)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2522)
at android.app.ActivityThread.access$800(ActivityThread.java:167)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1417)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5537)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:956)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:751)
Caused by java.lang.ClassNotFoundException: Didn't find class "co.getroad.investment.InvestmentFeatureImpl$Provider" on path: DexPathList[[zip file "/data/app/com.road.mobile-1/base.apk", zip file "/data/app/com.road.mobile-1/split_config.armeabi_v7a.apk", zip file "/data/app/com.road.mobile-1/split_config.mdpi.apk", zip file "/data/app/com.road.mobile-1/split_creditreport.config.mdpi.apk", zip file "/data/app/com.road.mobile-1/split_investment.config.mdpi.apk"],nativeLibraryDirectories=[/data/app/com.road.mobile-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 java.lang.Class.classForName(Class.java)
at java.lang.Class.forName(Class.java:308)
at java.lang.Class.forName(Class.java:272)
at com.road.mobile.InvestmentFeature.<clinit>(InvestmentFeature.java:75)
at com.road.mobile.home.viewmodel.DashboardViewModel.<init>(DashboardViewModel.java:25)
at com.road.mobile.home.viewmodel.DashboardViewModel$Factory.create(DashboardViewModel.java:32)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.road.mobile.home.fragment.DashboardFragment$dashboardViewModel$2.invoke(DashboardFragment.java:92)
at com.road.mobile.home.fragment.DashboardFragment$dashboardViewModel$2.invoke(DashboardFragment.java:80)
at kotlin.SynchronizedLazyImpl.getValue(SynchronizedLazyImpl.java:74)
at com.road.mobile.home.fragment.DashboardFragment.getDashboardViewModel(DashboardFragment.java)
at com.road.mobile.home.fragment.DashboardFragment.initFinancialToolsUi(DashboardFragment.java:218)
at com.road.mobile.home.fragment.DashboardFragment.initUI(DashboardFragment.java:159)
at com.road.mobile.home.fragment.DashboardFragment.onViewCreated(DashboardFragment.java:115)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:298)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1232)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1398)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1476)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1541)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2333)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2120)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2075)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1977)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2862)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2812)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at com.road.mobile.base.activity.BaseActivity.onStart(BaseActivity.java:116)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1228)
at android.app.Activity.performStart(Activity.java:5991)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2423)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2522)
at android.app.ActivityThread.access$800(ActivityThread.java:167)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1417)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5537)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:956)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:751)
Мы используем формат app-bundles (.aab) (динамическая доставка). Класс не найден в модуле инвестиционных функций, поэтому мы пытаемся вызвать метод в этом функциональном модуле - из модуля приложения через отражение - подход 1 отсюда https://medium.com/androiddevelopers/patterns-for-accessing-code-from-dynamic-feature-modules-7e5dca6f9123
object InvestmentFeature {
private const val PROVIDER_CLASS = "$PACKAGE_NAME.InvestmentFeatureImpl\$Provider"
val investmentModuleProvider = Class.forName(PROVIDER_CLASS).kotlin.objectInstance as InvestmentFeature.Provider
}
class DashboardViewModel constructor(activity: AppCompatActivity) : ViewModel() {
var investmentModule: InvestmentFeature? = null
var investmentProductsLiveData: LiveData<List<InvestmentProductEntity>>? = null
init {
// ExceptionInInitializerError is thrown here
investmentModule = investmentModuleProvider.get()
investmentProductsLiveData = investmentModule!!.getInvestmentProducts()
}
Это внутри модуля приложения:
interface InvestmentFeature {
fun getInvestmentProducts(): LiveData<List<InvestmentProductEntity>>
interface Provider {
fun get(): InvestmentFeature
}
}
Это внутри моего модуля инвестиционных функций:
class InvestmentFeatureImpl : InvestmentFeature {
override fun getInvestmentProducts(): LiveData<List<InvestmentProductEntity>> {
val repository = Repository.INSTANCE
return repository.getInvestmentProductsLiveData()
}
/**
* The provider singleton. It is accessed from the base app ViewModel through reflection.
*/
companion object Provider : InvestmentFeature.Provider {
override fun get(): InvestmentFeature {
return InvestmentFeatureImpl()
}
}
}
Я уже установил правила proguard для класса / интерфейса, но все еще не работают.
Обратите внимание, что он хорошо работает для некоторых устройств / пользователей, но не работает для других в производстве.
Как я могу решить эту проблему?