Closed patrickboisclair closed 10 months ago
NOTE for reference, im using ktor 2.3.5
Just a note that I'm running into the same issue.
Also when moving from io.insert-koin:koin-ktor.3.4.3 to 3.5.0 tests like the following start to fail:
`@TestInstance(TestInstance.Lifecycle.PER_CLASS) class DokumentRestControllerTest : KoinTest {
@JvmField
@RegisterExtension
@Suppress("unused")
val koinTestExtension = KoinTestExtension.create {
modules(
restKoinModule,
memoryPersistenceKoinTestModule,
)
}
@Test
fun testGetDokumentUnknown() = testApplication {
application {
dokumentModule()
} // call with unknown id should result in 404
client.get("/aktenordner/dokument/e58ed763-928c-4155-bee9-fdbaaadc15ff").apply {
assertEquals(HttpStatusCode.NotFound, status)
}
}
`
This works with 3.4.3, but with 3.5.0 I get
java.lang.IllegalStateException: No instance for key AttributeKey: KOIN at io.ktor.util.Attributes$DefaultImpls.get(Attributes.kt:62) at io.ktor.util.AttributesJvmBase.get(AttributesJvm.kt:15) at org.koin.ktor.ext.ApplicationExtKt.getKoin(ApplicationExt.kt:34) at org.codeshards.aktenordner.adapter.incoming.rest.DokumentRestControllerKt$dokumentModule$$inlined$inject$default$1.invoke(ApplicationExt.kt:78) at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) at org.codeshards.aktenordner.adapter.incoming.rest.DokumentRestControllerKt.dokumentModule$lambda$0(DokumentRestController.kt:29) at org.codeshards.aktenordner.adapter.incoming.rest.DokumentRestControllerKt.access$dokumentModule$lambda$0(DokumentRestController.kt:1) at org.codeshards.aktenordner.adapter.incoming.rest.DokumentRestControllerKt$dokumentModule$2$1$3.invokeSuspend(DokumentRestController.kt:43) at org.codeshards.aktenordner.adapter.incoming.rest.DokumentRestControllerKt$dokumentModule$2$1$3.invoke(DokumentRestController.kt) at org.codeshards.aktenordner.adapter.incoming.rest.DokumentRestControllerKt$dokumentModule$2$1$3.invoke(DokumentRestController.kt) at io.ktor.server.routing.Route$buildPipeline$1$1.invokeSuspend(Route.kt:116) at io.ktor.server.routing.Route$buildPipeline$1$1.invoke(Route.kt) at io.ktor.server.routing.Route$buildPipeline$1$1.invoke(Route.kt) at io.ktor.util.pipeline.DebugPipelineContext.proceedLoop(DebugPipelineContext.kt:80) at io.ktor.util.pipeline.DebugPipelineContext.proceed(DebugPipelineContext.kt:57) at io.ktor.util.pipeline.DebugPipelineContext.execute$ktor_utils(DebugPipelineContext.kt:63) at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77) at io.ktor.server.routing.Routing$executeResult$$inlined$execute$1.invokeSuspend(Pipeline.kt:478) at io.ktor.server.routing.Routing$executeResult$$inlined$execute$1.invoke(Pipeline.kt) at io.ktor.server.routing.Routing$executeResult$$inlined$execute$1.invoke(Pipeline.kt) at io.ktor.util.debug.ContextUtilsKt.initContextInDebugMode(ContextUtils.kt:17) at io.ktor.server.routing.Routing.executeResult(Routing.kt:190) at io.ktor.server.routing.Routing.interceptor(Routing.kt:64) at io.ktor.server.routing.Routing$Plugin$install$1.invokeSuspend(Routing.kt:140) at io.ktor.server.routing.Routing$Plugin$install$1.invoke(Routing.kt) at io.ktor.server.routing.Routing$Plugin$install$1.invoke(Routing.kt) at io.ktor.util.pipeline.DebugPipelineContext.proceedLoop(DebugPipelineContext.kt:80) at io.ktor.util.pipeline.DebugPipelineContext.proceed(DebugPipelineContext.kt:57) at io.ktor.server.engine.BaseApplicationEngineKt$installDefaultTransformationChecker$1.invokeSuspend(BaseApplicationEngine.kt:124) at io.ktor.server.engine.BaseApplicationEngineKt$installDefaultTransformationChecker$1.invoke(BaseApplicationEngine.kt) at io.ktor.server.engine.BaseApplicationEngineKt$installDefaultTransformationChecker$1.invoke(BaseApplicationEngine.kt) at io.ktor.util.pipeline.DebugPipelineContext.proceedLoop(DebugPipelineContext.kt:80) at io.ktor.util.pipeline.DebugPipelineContext.proceed(DebugPipelineContext.kt:57) at io.ktor.util.pipeline.DebugPipelineContext.execute$ktor_utils(DebugPipelineContext.kt:63) at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77) at io.ktor.server.testing.TestApplicationEngine$3$invokeSuspend$$inlined$execute$1.invokeSuspend(Pipeline.kt:478) at io.ktor.server.testing.TestApplicationEngine$3$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt) at io.ktor.server.testing.TestApplicationEngine$3$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt) at io.ktor.util.debug.ContextUtilsKt.initContextInDebugMode(ContextUtils.kt:17) at io.ktor.server.testing.TestApplicationEngine$3.invokeSuspend(TestApplicationEngine.kt:310) at io.ktor.server.testing.TestApplicationEngine$3.invoke(TestApplicationEngine.kt) at io.ktor.server.testing.TestApplicationEngine$3.invoke(TestApplicationEngine.kt) at io.ktor.server.testing.TestApplicationEngine$2.invokeSuspend(TestApplicationEngine.kt:90) at io.ktor.server.testing.TestApplicationEngine$2.invoke(TestApplicationEngine.kt) at io.ktor.server.testing.TestApplicationEngine$2.invoke(TestApplicationEngine.kt) at io.ktor.util.pipeline.DebugPipelineContext.proceedLoop(DebugPipelineContext.kt:80) at io.ktor.util.pipeline.DebugPipelineContext.proceed(DebugPipelineContext.kt:57) at io.ktor.util.pipeline.DebugPipelineContext.execute$ktor_utils(DebugPipelineContext.kt:63) at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77) at io.ktor.server.testing.TestApplicationEngine$handleRequestNonBlocking$2$invokeSuspend$$inlined$execute$1.invokeSuspend(Pipeline.kt:478) at io.ktor.server.testing.TestApplicationEngine$handleRequestNonBlocking$2$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt) at io.ktor.server.testing.TestApplicationEngine$handleRequestNonBlocking$2$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt) at io.ktor.util.debug.ContextUtilsKt.initContextInDebugMode(ContextUtils.kt:17) at io.ktor.server.testing.TestApplicationEngine$handleRequestNonBlocking$2.invokeSuspend(TestApplicationEngine.kt:309) at io.ktor.server.testing.TestApplicationEngine$handleRequestNonBlocking$2.invoke(TestApplicationEngine.kt) at io.ktor.server.testing.TestApplicationEngine$handleRequestNonBlocking$2.invoke(TestApplicationEngine.kt) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:78) at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:167) at kotlinx.coroutines.BuildersKt.withContext(Unknown Source) at io.ktor.server.testing.TestApplicationEngine.handleRequestNonBlocking$ktor_server_test_host(TestApplicationEngine.kt:224) at io.ktor.server.testing.TestApplicationEngine.handleRequestNonBlocking$ktor_server_test_host$default(TestApplicationEngine.kt:211) at io.ktor.server.testing.client.TestHttpClientEngine.runRequest(TestHttpClientEngine.kt:70) at io.ktor.server.testing.client.TestHttpClientEngine.execute(TestHttpClientEngine.kt:55) at io.ktor.server.testing.client.DelegatingTestClientEngine.execute(DelegatingTestClientEngine.kt:55) at io.ktor.client.engine.HttpClientEngine$executeWithinCallContext$2.invokeSuspend(HttpClientEngine.kt:99) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108) at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115) at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
Same here, downgraded to 3.4.3 and worked
Have you tried kotlin-bom
to manage dependencies? I was having the same problem and found out that I was using koin-ktor
v3.5.0 instead of v3.5.1 (together with koin-core-jvm:3.5.0). I think it has been introduced recently according to the changelog and this article.
@tuncererdogan Ty for the tips !
I tried providing the BOM, but it still gives me the same error.
I'm having the same issue, for what it's worth.
same problem here
Just a quick note that I've opened a separate issue for the problem with the failing tests after upgrading to 3.5.0
seems that isolated context feature is not working well. @patrickboisclair can you provide more details of the code that fail? is it running outside of Ktor?
I really need more details to help from anyone from this thread
@arnaudgiuliani , thanks for looking into this. I've uploaded a small sample project in the related issue that I mentioned above. In the version that is checked in I already applied the workaround for starting Koin but I can easily revert that. Then you should be able to recreate the problem with a simple gradle call. Would that help you?
yes 👍
@arnaudgiuliani I checked and the version I have pushed to Gitlab is already the one that exposes the problem. Here are the steps to reproduce:
Change koin_ktor_version
to 3.5.0 in gradle.properties
gradle clean
gradle build -x test
gradle run
Access http://localhost:8080/aktenordner/dokument from a browser or via curl.
You should see a stacktrace like this:
2023-10-31 18:29:15.798 [main] INFO ktor.application - Responding at http://0.0.0.0:8080
2023-10-31 18:29:51.575 [eventLoopGroupProxy-4-2] INFO [Koin] - | Scope 'q:'org.koin.ktor.plugin.RequestScope'' not defined. Creating it ...
2023-10-31 18:29:51.590 [eventLoopGroupProxy-4-2] ERROR ktor.application - Unhandled: GET - /aktenordner/dokument
java.lang.IllegalStateException: KoinApplication has not been started
at org.koin.core.context.GlobalContext.get(GlobalContext.kt:36)
at org.koin.core.component.KoinComponent$DefaultImpls.getKoin(KoinComponent.kt:33)
at org.codeshards.aktenordner.application.service.ListDokumenteService.getKoin(ListDokumenteService.kt:10)
at org.codeshards.aktenordner.application.service.ListDokumenteService$special$$inlined$inject$default$1.invoke(KoinComponent.kt:68)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at org.codeshards.aktenordner.application.service.ListDokumenteService.getListDokumentePort(ListDokumenteService.kt:12)
at org.codeshards.aktenordner.application.service.ListDokumenteService.listDokumente(ListDokumenteService.kt:14)
at org.codeshards.aktenordner.adapter.incoming.rest.DokumentRestControllerKt.handleListDokumente(DokumentRestController.kt:156)
at org.codeshards.aktenordner.adapter.incoming.rest.DokumentRestControllerKt.access$handleListDokumente(DokumentRestController.kt:1)
at org.codeshards.aktenordner.adapter.incoming.rest.DokumentRestControllerKt$dokumentModule$2$1$1.invokeSuspend(DokumentRestController.kt:37)
at org.codeshards.aktenordner.adapter.incoming.rest.DokumentRestControllerKt$dokumentModule$2$1$1.invoke(DokumentRestController.kt)
at org.codeshards.aktenordner.adapter.incoming.rest.DokumentRestControllerKt$dokumentModule$2$1$1.invoke(DokumentRestController.kt)
at io.ktor.server.routing.Route$buildPipeline$1$1.invokeSuspend(Route.kt:116)
at io.ktor.server.routing.Route$buildPipeline$1$1.invoke(Route.kt)
at io.ktor.server.routing.Route$buildPipeline$1$1.invoke(Route.kt)
at io.ktor.util.pipeline.DebugPipelineContext.proceedLoop(DebugPipelineContext.kt:80)
at io.ktor.util.pipeline.DebugPipelineContext.proceed(DebugPipelineContext.kt:57)
at io.ktor.util.pipeline.DebugPipelineContext.execute$ktor_utils(DebugPipelineContext.kt:63)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77)
at io.ktor.server.routing.Routing$executeResult$$inlined$execute$1.invokeSuspend(Pipeline.kt:478)
at io.ktor.server.routing.Routing$executeResult$$inlined$execute$1.invoke(Pipeline.kt)
at io.ktor.server.routing.Routing$executeResult$$inlined$execute$1.invoke(Pipeline.kt)
at io.ktor.util.debug.ContextUtilsKt.initContextInDebugMode(ContextUtils.kt:17)
at io.ktor.server.routing.Routing.executeResult(Routing.kt:190)
at io.ktor.server.routing.Routing.interceptor(Routing.kt:64)
at io.ktor.server.routing.Routing$Plugin$install$1.invokeSuspend(Routing.kt:140)
at io.ktor.server.routing.Routing$Plugin$install$1.invoke(Routing.kt)
at io.ktor.server.routing.Routing$Plugin$install$1.invoke(Routing.kt)
at io.ktor.util.pipeline.DebugPipelineContext.proceedLoop(DebugPipelineContext.kt:80)
at io.ktor.util.pipeline.DebugPipelineContext.proceed(DebugPipelineContext.kt:57)
at io.ktor.server.engine.BaseApplicationEngineKt$installDefaultTransformationChecker$1.invokeSuspend(BaseApplicationEngine.kt:124)
at io.ktor.server.engine.BaseApplicationEngineKt$installDefaultTransformationChecker$1.invoke(BaseApplicationEngine.kt)
at io.ktor.server.engine.BaseApplicationEngineKt$installDefaultTransformationChecker$1.invoke(BaseApplicationEngine.kt)
at io.ktor.util.pipeline.DebugPipelineContext.proceedLoop(DebugPipelineContext.kt:80)
at io.ktor.util.pipeline.DebugPipelineContext.proceed(DebugPipelineContext.kt:57)
at io.ktor.util.pipeline.DebugPipelineContext.execute$ktor_utils(DebugPipelineContext.kt:63)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77)
at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1$invokeSuspend$$inlined$execute$1.invokeSuspend(Pipeline.kt:478)
at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt)
at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt)
at io.ktor.util.debug.ContextUtilsKt.initContextInDebugMode(ContextUtils.kt:17)
at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1.invokeSuspend(DefaultEnginePipeline.kt:123)
at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1.invoke(DefaultEnginePipeline.kt)
at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1.invoke(DefaultEnginePipeline.kt)
at io.ktor.util.pipeline.DebugPipelineContext.proceedLoop(DebugPipelineContext.kt:80)
at io.ktor.util.pipeline.DebugPipelineContext.proceed(DebugPipelineContext.kt:57)
at io.ktor.util.pipeline.DebugPipelineContext.execute$ktor_utils(DebugPipelineContext.kt:63)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77)
at io.ktor.server.netty.NettyApplicationCallHandler$handleRequest$1$invokeSuspend$$inlined$execute$1.invokeSuspend(Pipeline.kt:478)
at io.ktor.server.netty.NettyApplicationCallHandler$handleRequest$1$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt)
at io.ktor.server.netty.NettyApplicationCallHandler$handleRequest$1$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt)
at io.ktor.util.debug.ContextUtilsKt.initContextInDebugMode(ContextUtils.kt:17)
at io.ktor.server.netty.NettyApplicationCallHandler$handleRequest$1.invokeSuspend(NettyApplicationCallHandler.kt:119)
at io.ktor.server.netty.NettyApplicationCallHandler$handleRequest$1.invoke(NettyApplicationCallHandler.kt)
at io.ktor.server.netty.NettyApplicationCallHandler$handleRequest$1.invoke(NettyApplicationCallHandler.kt)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:44)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:112)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
at kotlinx.coroutines.BuildersKt.launch(Unknown Source)
at io.ktor.server.netty.NettyApplicationCallHandler.handleRequest(NettyApplicationCallHandler.kt:37)
at io.ktor.server.netty.NettyApplicationCallHandler.channelRead(NettyApplicationCallHandler.kt:29)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:61)
at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:425)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.ktor.server.netty.EventLoopGroupProxy$Companion.create$lambda$1$lambda$0(NettyApplicationEngine.kt:296)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:829)
If you want to see the version with the workaround ( startKoin
instead of install(Koin)
) just switch the comment between the two versions of Application.module() in org/codeshards/Application.kt
Same crash with this code for quartz job factory:
class DiJobFactory : JobFactory, KoinComponent {
override fun newJob(
bundle: TriggerFiredBundle?,
scheduler: Scheduler?,
): Job {
if (bundle != null) {
val jobClass = bundle.jobDetail.jobClass
return getKoin().get(jobClass.kotlin)
}
throw NotImplementedError("Job Factory error")
}
}
Fixed it with GlobalContext.startKoin
install(Koin) {
modules(modules)
GlobalContext.startKoin(this)
}
koin-bom 3.5.1
We encountered this issue ("KoinApplication has not been started") when updating a Ktor app to 3.5.1 (was 3.4.3). I cross referenced and we are accurately following the documentation and example code by using just install(Koin) { ... }
and no explicit startKoin
call.
This issue has been around for weeks - is there an ETA for a fix? Do we know which change causes the error?
I looking precisely how to revert the APi and keep the context isolation for Ktor. This is why I'm gathering feedbacks and samples. ETA for the fix is around 2 weeks max.
I reverted back the startKoin in the main Ktor plugin. I will publish a RC build to let you test 👍
Let's reopen it if someone sees a failure in RC release.
Just for the record: using 3.5.2-RC1 everything works fine for me. Sorry for the late feedback.
I upgraded from koin 3.4.0 to 3.5.1 for Ktor and since then I get the error:
Exception in thread "DefaultDispatcher-worker-8" java.lang.IllegalStateException: KoinApplication has not been started at org.koin.core.context.GlobalContext.get(GlobalContext.kt:36) at org.koin.core.component.KoinComponent$DefaultImpls.getKoin(KoinComponent.kt:33) at com.noovelia.nooveliabeats.core.hostedservices.GrpcServer.getKoin(GrpcServer.kt:16) at com.noovelia.nooveliabeats.core.hostedservices.GrpcServer$special$$inlined$inject$default$1.invoke(KoinComponent.kt:68) at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) at com.noovelia.nooveliabeats.core.hostedservices.GrpcServer.getLoggingService(GrpcServer.kt:30) at com.noovelia.nooveliabeats.core.hostedservices.GrpcServer.access$getLoggingService(GrpcServer.kt:16) at com.noovelia.nooveliabeats.core.hostedservices.GrpcServer$run$1.invokeSuspend(GrpcServer.kt:35) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108) at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115) at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
Instead of using: install(Koin), I tried with startKoin and it seems to work.
Koin module and version: