I have really hard time trying to migrate koin annotations from 1.x to 2.x. Multiplatform app, but e...
m
I have really hard time trying to migrate koin annotations from 1.x to 2.x. Multiplatform app, but everything works fine except for the android module. In 1.x I had my AndroidModule which scanned through the android gradle module and found all 46 viewmodels just fine. Now simply changing version of koin-annotations to 2.x makes this AndroidModule to be unresolved (it stops being generated). I tried using the deprecated defaultModule (with KSP flag) and it does generate but somehow it only generates definitions for 22 of my viewmodels.
Copy code
kotlin = "2.1.10"
ksp = "2.1.10-1.0.31" //tried ksp2 as well
koin = "4.1.1"
koinAnnotations = "2.2.0"
More details in 🧵 as not to spam here too much
It builds but fails at runtime (
Caused by: org.koin.core.error.NoDefinitionFoundException: No definition found for type 'com.example.android.presentation.main.MainViewModel). Check your Modules configuration and add missing type and/or qualifier!
). I tried both legacy and new viewmodels via appropriate ksp flag (noticed that 1.x generated the legacy viewmodels). The imports and
@KoinViewModel
annotation are the same for generated and non-generated viewmodels. It doesn't matter if I generate a viewmodel with dependencies or not (removed them to be sure it's not the issue). The visibility of those viewmodels doesn't seem to matter (internal or public), their dependencies too (even copied dependencies of the working one to non-working one) or even if they are placed in the same package.
generated
Copy code
package com.example.android.presentation.auth.incomplete

...
import org.koin.android.annotation.KoinViewModel

@KoinViewModel
internal class IncompleteUserViewModel(
    private val updateAuthUserDataUseCase: UpdateAuthUserDataUseCase,
    savedStateHandle: SavedStateHandle,
) : ViewModel() {
Not generated
Copy code
package com.example.android.presentation.auth.incomplete

...
import org.koin.android.annotation.KoinViewModel

@KoinViewModel
internal class MainViewModel(
    private val updateAuthUserDataUseCase: UpdateAuthUserDataUseCase,
    savedStateHandle: SavedStateHandle,
) : ViewModel() {
I would gladly move from defaultModule to the new approach, but it seems like the problem is elsewhere
and the report from generation
Copy code
w: [ksp] Generating 'defaultModule' with 22 definitions
w: [ksp] Koin Configuration Generated in 118.316417ms
w: [ksp] [Deprecation] 'defaultModule' generation is deprecated. Use KSP argument arg("KOIN_DEFAULT_MODULE","true") to activate default module generation.
w: [ksp] Koin Configuration Generated in 7.031833ms
w: [ksp] Koin Configuration Check ...
w: [ksp] no module found
w: [ksp] Koin Configuration Check done in 8.295750ms
This
no module found
is a bit suspicious
any help appreciated, I've hit a wall. Since it looks so random I assume there is something obvious I might be missing
There seems to be some correlation between modules not being generated and not having savedStateHandle but adding it didn't help.
After fighting it for several hours I am pretty sure that the problem is in generating code in android module. It works in kotlin multiplatform modules with appropriate dependencies but doesn't in android module. In a very similar project which is CMP instead of KMP and has its android module multiplatform it works fine. And in pure android module with koin annotation 2.x the
module
is never generated (nor are some of the viewmodels inside default module and it's probably part of the same issue)
Copy code
@Module
@ComponentScan("com.example.android")
class AndroidModule {
    @Factory
    fun provideDummy() = Dummy()
}

val androidModule = AndroidModule().module

@Single
class Dummy
I just checked in another project in our company. It's a pure android, single gradle module project. Result is the same. After changing koin-annotations from 1.3.0 to 2.2.0: 1. `@Module`s stop generating completely 2. default modules generates but only contains 19 out of 58 viewmodels that the original one has.
s
interesting 1
m
for me it fails on android modules and works on multiplatform and also the breaking project is still on a bit older non ksp2 version and koin-annotations 2.2.0, not the latest (although tried ksp2 as well without success)
I am trying to isolate the issue, but it's super random, right now I am simply copying stuff from a not working large module to a wroking module and see when it breaks
OMG I got it. Had to use the compiler from source and with added debugging and claude code I found it. It's most probably a race condition between different ksp processors which I have 4 in production project. In my case the raamcosta destinations processor which hasn't yet generated its stuff which made some of the viewmodels invalid which in turn exits the processor too early without generating modules. And then in next round only the previously invalid viewmodels are generated.
Copy code
val invalidSymbols = koinMetaDataScanner.findInvalidSymbols(resolver)
  if (invalidSymbols.isNotEmpty()) {
      return invalidSymbols  //  EXIT EARLY - Don't generate ANYTHING
  }
It created a super weird behavior where it only generates e.g. 22/46 viewmodels, even more weirdly, the exact ones that are marked invalid in log mind blown. The fix would be to create what we can in each round without exiting early. A quick and dirty implementation of the fix (with claudes help) that works in my case: https://github.com/micHar/koin-annotations/pull/1/files If you want, I'd be glad to prepare a clean MR @arnaud.giuliani, but would love to hear your thoughts about this issue first, maybe I got that all wrong. I'm also not sure if there shouldn't be some additional check / fail during the compilation that would explicitly fail the processing and say what's wrong, but I'm not proficient in ksp processors.