InsertKoinIO / koin

Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform
https://insert-koin.io
Apache License 2.0
9.12k stars 721 forks source link

Random crashes after integration koin-androidx-workmanager and updating to 3.3.2 #1513

Closed milkaman closed 1 year ago

milkaman commented 1 year ago

Describe the bug We finally decided to integrate koin-androidx-workmanager in our project. Previously, we used KoinComponent declaration for Worker-classes. Also we moved to 3.3.2 and 3.4.1 (for Compose dependency) versions of Koin libraries.

Since next release we have been experiencing strange NoBeanDefFoundException-crashes. It can't be reproduced during development and it seems like it could only be connected with some energy saving modes on some devices.

image

For integration, we followed steps at this page: https://insert-koin.io/docs/reference/koin-android/workmanager The only difference that our Application class doesn't implement KoinComponent interface (is it a reason or just outdated??), but this moment is not highlighted on the page and there is no such case on the main setup page

So Koin is not new for the project, it lives for 2+ years, but it's the first problem of usage just after integration of wokmanager-module and updating version (from 3.2.0)

It only affects ~0.9-1% of all users but it matters 🥲

To Reproduce There is no any known step to reproduce, it just happen at some moment

Koin project used and used version (please complete the following information): Current dependecies: io.insert-koin:koin-android:3.3.2 io.insert-koin:koin-androidx-compose:3.4.1 io.insert-koin:koin-androidx-workmanager:3.3.2

Additional moduleDefinition WorkManager has 2.7.1 versions itself

arnaudgiuliani commented 1 year ago

Hello,

The only difference that our Application class doesn't implement KoinComponent interface (is it a reason or just outdated??)

Not needed effectively.

What are the definitions, not found (with NoBeanDefFoundException)? is it related to WorkManager?

milkaman commented 1 year ago

Yeah, definitions are various implementations of Worker-s (CoroutineWorker) It's an example of stacktrace below

Caused by org.koin.core.error.InstanceCreationException: Could not create instance for '[Factory:'e50.k',binds:e50.i]' at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:59) at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:38) at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.java:106) at org.koin.core.scope.Scope.resolveValue(Scope.kt:246) at org.koin.core.scope.Scope.resolveInstance(Scope.kt:231) at org.koin.core.scope.Scope.get(Scope.kt:210) --- (our modules) at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:52) at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:38) at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.java:106) at org.koin.core.scope.Scope.resolveValue(Scope.kt:246) at org.koin.core.scope.Scope.resolveInstance(Scope.kt:231) at org.koin.core.scope.Scope.get(Scope.kt:210) at org.koin.core.scope.Scope.getOrNull(Scope.kt:175) at org.koin.androidx.workmanager.factory.KoinWorkerFactory.createWorker(KoinWorkerFactory.kt:47) at androidx.work.DelegatingWorkerFactory.createWorker(DelegatingWorkerFactory.java:71) at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:83) at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:245) at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:137) at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:919)

arnaudgiuliani commented 1 year ago

did you tried koin-android:3.4.0? Jetpack ocmpose version base android versions are different. koin-androidx-workmanagerlast patch is 3.4.0

kapin-k commented 1 year ago

@arnaudgiuliani I have noticed the issue mentioned above with a similar stack trace.

I was able to replicate the stack trace on a KoinTest when trying to verify the instance creation. (wondering if it is due to the usage of mocked constructor dependecies). Can you confirm if this is expected?

@Test
    fun test() {
        val testModule: Module = module {
            single { mock<MyRepository>() }
            worker { (parameters: WorkerParameters) ->
                MyCoroutineWorker(
                    context = get(),
                    repository = get(),
                    params = parameters,
                )
            }
        }
        startKoin { androidContext(application) }
        loadKoinModules(testModule)
        get<MyRepository>().shouldNotBeNull() // No issues with resolving instance
        get<MyCoroutineWorker>().shouldNotBeNull() // throws Fatal error: Could not create instance. err getScope()
        unloadKoinModules(testModule)
        stopKoin()
    }
arnaudgiuliani commented 1 year ago

@kapin-k in your test, your are not loading any work manager factory, injection can't be done then.

arnaudgiuliani commented 1 year ago

let's see with koin-android 3.5.0 and parameter race condition fix https://github.com/InsertKoinIO/koin/pull/1561 how it goes 👍