InsertKoinIO / koin

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

Cannot invoke "org.koin.core.module.Module.getIncludedModules()" because "it" is null #1702

Closed yektasarioglu closed 10 months ago

yektasarioglu commented 10 months ago

I'm getting; Cannot invoke "org.koin.core.module.Module.getIncludedModules()" because "it" is null

To Reproduce

fun Application.configureKoin() {
    install(Koin) {
        slf4jLogger()
        modules(dataModule, domainModule)
    }
}    

val dataModule = module {
    includes(remoteDataSourceModule, repositoryModule)
}

val remoteDataSourceModule = module {
    single { SampleRemoteDataSource() }
}

val repositoryModule = module {
    single { SampleRepo() }
}

Expected behavior No error whatsoever when composing modules like the above with the help of includes

Koin module and version:

arnaudgiuliani commented 10 months ago

Can you push your dataModule definition at the bottom? There is a compilation issue regarding includes and module definitions

ludovicroland commented 10 months ago

Hello @arnaudgiuliani,

I am also facing the same issue using koin-bom:3.5.1:

implementation(platform("io.insert-koin:koin-bom:3.5.1"))
implementation("io.insert-koin:koin-core")
implementation("io.insert-koin:koin-android")

It's super easy to reproduce with few code.

For example:

class ZeroClass {
}

class FirstClass : KoinComponent {

  val zeroClass: ZeroClass by inject()

}

class SecondClass : KoinComponent {

  val zeroClass: ZeroClass by inject()

}

class ThirdClass : KoinComponent {

  val firstClass: FirstClass by inject()

  val secondClass: FirstClass by inject()

}

Then the module code:

val globalModule = module {
  includes(
    moduleZero,
    firstAndSecondZero
  )
}

val moduleZero = module {
  single { ZeroClass() }
}

val firstAndSecondZero = module {
  single { FirstClass() }
  single { SecondClass() }
}

And then the Application code:

class MyApplication : Application() {

  override fun onCreate() {
    super.onCreate()

    startKoin {
      androidContext(this@MyApplication)
      modules(globalModule)
    }
  }
}

I also tried to avoid to use the KoinComponent interface and use the get() function instead:

class ZeroClass {
}

class FirstClass(val zeroClass: ZeroClass)

class SecondClass(val zeroClass: ZeroClass)

class ThirdClass(val firstClass: FirstClass, val secondClass: FirstClass)

Then the module code:

val globalModule = module {
  includes(
    moduleZero,
    firstAndSecondZero
  )
}

val moduleZero = module {
  single { ZeroClass() }
}

val firstAndSecondZero = module {
  single { FirstClass(get()) }
  single { SecondClass(get()) }
}

But the result is the same. It crashes directly with the following stackstrace:

FATAL EXCEPTION: main
Process: com.rolandl.kointest, PID: 12814
java.lang.RuntimeException: Unable to create applicationWcom.rolandl.kointest.MyApplication: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List org.koin.core.module.Module.getIncludedModules()' on a null object reference
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7003)
at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2236)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List org.koin.core.module.Module.getIncludedModules()' on a null object reference
at org.koin.core.module.ModuleKt.flatten$flat(Module.kt:242)
at org.koin.core.module.ModuleKt.flatten$flat(Module.kt:242)
at org.koin.core.module.ModuleKt.flatten(Module.kt:245)
at org.koin.core.Koin.loadModules(Koin.kt:310)
at org.koin.core.KoinApplication.loadModules(KoinApplication.kt:87)
at org.koin.core.KoinApplication.modules(KoinApplication.kt:65)
at org.koin.core.KoinApplication.modules(KoinApplication.kt:44)
at com.rolandl.kointest.MyApplication$onCreate$1.invoke(MyApplication.kt:14)
at com.rolandl.kointest.MyApplication$onCreate$1.invoke(MyApplication.kt:12)
at org.koin.core.context.GlobalContext.startKoin(GlobalContext.kt:64)
at org.koin.core.context.DefaultContextExtKt.startKoin(DefaultContextExt.kt:40)
at com.rolandl.kointest.MyApplication.onCreate(MyApplication.kt:12)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6998)
at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2236) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loopOnce(Looper.java:205) 
at android.os.Looper.loop(Looper.java:294) 
at android.app.ActivityThread.main(ActivityThread.java:8177) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
yektasarioglu commented 10 months ago

Can you push your dataModule definition at the bottom? There is a compilation issue regarding includes and module definitions

It worked like charm. Thanks, @arnaudgiuliani 👍

guillermomuntaner commented 10 months ago

Just experienced this. The workaround of moving the module using includes to the bottom (after the modules it includes) worked 👍

arnaudgiuliani commented 10 months ago

thanks 👍