koin
koin copied to clipboard
NoBeanDefFoundException in WorkManager
Describe the bug
We get occasional crashes when using koin-androidx-workmanager
to inject our worker classes. It seems like this is a continuation of #1623.
Fatal Exception: java.lang.Error: org.koin.core.error.InstanceCreationException: Could not create instance for '[Factory:'my.package.SomeWorker',qualifier:q:'my.package.SomeWorker',binds:androidx.work.ListenableWorker]'
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1173)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
Caused by org.koin.core.error.InstanceCreationException: Could not create instance for '[Factory:'my.package.SomeWorker',qualifier:q:'my.package.SomeWorker',binds:androidx.work.ListenableWorker]'
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:57)
at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:38)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:116)
at org.koin.core.scope.Scope.resolveValue(Scope.kt:247)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:233)
at org.koin.core.scope.Scope.get(Scope.kt:212)
at org.koin.core.scope.Scope.getOrNull(Scope.kt:177)
at org.koin.core.scope.Scope.getOrNull$default(Scope.kt:160)
at org.koin.androidx.workmanager.factory.KoinWorkerFactory.createWorker(KoinWorkerFactory.kt:41)
at androidx.work.DelegatingWorkerFactory.createWorker(DelegatingWorkerFactory.java:71)
at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:83)
at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:243)
at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:145)
at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
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:920)
Caused by org.koin.core.error.NoBeanDefFoundException: No definition found for type 'my.package.SomeWorker'. Check your Modules configuration and add missing type and/or qualifier!
at org.koin.core.scope.Scope.throwDefinitionNotFound(Scope.kt:301)
at org.koin.core.scope.Scope.resolveValue(Scope.kt:271)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:233)
at org.koin.core.scope.Scope.get(Scope.kt:212)
at org.koin.core.scope.Scope.get$default(Scope.kt:136)
at my.package.MyWorkerModuleKt$workersModule$1$11.invoke(MyWorkerModule.kt:51)
at my.package.MyWorkerModuleKt$workersModule$1$11.invoke(MyWorkerModule.kt:47)
at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:38)
at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:116)
at org.koin.core.scope.Scope.resolveValue(Scope.kt:247)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:233)
at org.koin.core.scope.Scope.get(Scope.kt:212)
at org.koin.core.scope.Scope.getOrNull(Scope.kt:177)
at org.koin.core.scope.Scope.getOrNull$default(Scope.kt:160)
at org.koin.androidx.workmanager.factory.KoinWorkerFactory.createWorker(KoinWorkerFactory.kt:41)
at androidx.work.DelegatingWorkerFactory.createWorker(DelegatingWorkerFactory.java:71)
at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:83)
at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:243)
at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:145)
at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
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:920)
To Reproduce
Our flow is as follows:
- We removed the default WorkManager initializer from the AndroidManifest
- We use an Initializer from the AndroidX Startup component to start Koin and set up the Koin WorkManager factory.
- There is a second Initializer that enqueues a periodic WorkRequest in WorkManager. This worker initializer depends on our Koin initializer so Koin should be initialized.
- The app also enqueues some one time work when the first activity is created.
Both the periodic and the one time workers produce NoBeanDefFoundEception crashes. It only happens to a small percentage of users, but it still happens with every release we make.
Koin module and version:
- Koin 3.5.1
- AndroidX Startup 1.1.1
- AndroidX WorkManager 2.8.1
Hi, I have the same issue. Is there any solution or workaround for this?
We ended up removing the koin-androidx-workmanager
library completely and made our workers KoinComponents
so they can get or inject their dependencies when they actually do the work.
class MyWorker(
appContext: Context,
params: WorkerParameters,
) : Worker(appContext, params),
KoinComponent {
// Use `by inject()` to get a lazy dependency.
private val myDependency: SomeClass by inject()
override suspend fun doWork(): Result {
// Only access the dependency in `doWork()`
myDependency.doSomething()
TODO("Return a result")
}
}
This makes the class more difficult to test but at least the crashes went away. I guess that this approach gives Koin a little more time to get the dependency graph ready.
Can you check how I setup it in NowInAndroid, and compare with yours? https://github.com/InsertKoinIO/nowinandroid
That is a big project to quickly check for the setup! 😄 Are you talking about the way you manually trigger the SyncWorker in the app's Application right here?
I am afraid that we have too much code relying on having Koin initialized via the AndroidX Startup library to quickly make this change. I should really put together a demo project to help figure out the cause of this crash rather than try to find a workaround.
Seems that worker is not well defined. But it needs deeper investigation on your side 🤔