[BUG][kotlin-client][multiplatform] "NoSuchMethodError" in runtime when starting ktor server with Kotlin 1.5.10
Created by: krzema12
Bug Report Checklist
-
Have you provided a full/minimal spec to reproduce the issue? -
Have you validated the input using an OpenAPI validator (example)? -
Have you tested with the latest master to confirm the issue still exists? -
Have you searched for related issues/PRs? -
What's the actual output vs expected output? -
[Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
When generating a Kotlin client using the multiplatform approach, the generated module builds fine, but it fails in runtime when I consume it from my project that includes a ktor server. It fails at the moment of installing ContentNegotiation
feature:
fun Application.module() {
install(ContentNegotiation) { // <<<<<<<<<<<< FAILS HERE
json()
}
}
The exact stack trace:
$ ./gradlew run
> Configure project :generated-client
Kotlin Multiplatform Projects are an experimental feature.
Some Kotlin/Native targets cannot be built on this linux_x64 machine and are disabled:
* In project ':':
* targets 'iosArm64', 'iosX64' (can be built with a macos_x64 host)
To hide this message, add 'kotlin.native.ignoreDisabledTargets=true' to the Gradle properties.
> Task :backend:run FAILED
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at kotlin.reflect.jvm.internal.calls.CallerImpl$Method.callMethod(CallerImpl.kt:97)
at kotlin.reflect.jvm.internal.calls.CallerImpl$Method$Static.call(CallerImpl.kt:106)
at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:108)
at kotlin.reflect.jvm.internal.KCallableImpl.callDefaultMethod$kotlin_reflection(KCallableImpl.kt:159)
at kotlin.reflect.jvm.internal.KCallableImpl.callBy(KCallableImpl.kt:112)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.callFunctionWithInjection(ApplicationEngineEnvironmentReloading.kt:406)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.executeModuleFunction(ApplicationEngineEnvironmentReloading.kt:360)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.access$executeModuleFunction(ApplicationEngineEnvironmentReloading.kt:35)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$launchModuleByName$1.invoke(ApplicationEngineEnvironmentReloading.kt:311)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$launchModuleByName$1.invoke(ApplicationEngineEnvironmentReloading.kt:35)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartupFor(ApplicationEngineEnvironmentReloading.kt:335)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.launchModuleByName(ApplicationEngineEnvironmentReloading.kt:310)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.access$launchModuleByName(ApplicationEngineEnvironmentReloading.kt:35)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:299)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:35)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartup(ApplicationEngineEnvironmentReloading.kt:317)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.instantiateAndConfigureApplication(ApplicationEngineEnvironmentReloading.kt:297)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.createApplication(ApplicationEngineEnvironmentReloading.kt:138)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.start(ApplicationEngineEnvironmentReloading.kt:270)
at io.ktor.server.cio.CIOApplicationEngine$serverJob$1$2.invokeSuspend(CIOApplicationEngine.kt:62)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Caused by: java.lang.NoSuchMethodError: 'kotlinx.serialization.json.Json kotlinx.serialization.json.JsonKt.Json$default(kotlinx.serialization.json.Json, kotlin.jvm.functions.Function1, int, java.lang.Object)'
at io.ktor.serialization.JsonSupportKt.<clinit>(JsonSupport.kt:29)
at ExampleApplicationKt$module$1.invoke(ExampleApplication.kt:10)
at ExampleApplicationKt$module$1.invoke(ExampleApplication.kt:9)
at io.ktor.features.ContentNegotiation$Feature.install(ContentNegotiation.kt:104)
at io.ktor.features.ContentNegotiation$Feature.install(ContentNegotiation.kt:97)
at io.ktor.application.ApplicationFeatureKt.install(ApplicationFeature.kt:68)
at ExampleApplicationKt.module(ExampleApplication.kt:9)
... 30 more
Exception in thread "DefaultDispatcher-worker-1" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at kotlin.reflect.jvm.internal.calls.CallerImpl$Method.callMethod(CallerImpl.kt:97)
at kotlin.reflect.jvm.internal.calls.CallerImpl$Method$Static.call(CallerImpl.kt:106)
at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:108)
at kotlin.reflect.jvm.internal.KCallableImpl.callDefaultMethod$kotlin_reflection(KCallableImpl.kt:159)
at kotlin.reflect.jvm.internal.KCallableImpl.callBy(KCallableImpl.kt:112)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.callFunctionWithInjection(ApplicationEngineEnvironmentReloading.kt:406)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.executeModuleFunction(ApplicationEngineEnvironmentReloading.kt:360)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.access$executeModuleFunction(ApplicationEngineEnvironmentReloading.kt:35)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$launchModuleByName$1.invoke(ApplicationEngineEnvironmentReloading.kt:311)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$launchModuleByName$1.invoke(ApplicationEngineEnvironmentReloading.kt:35)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartupFor(ApplicationEngineEnvironmentReloading.kt:335)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.launchModuleByName(ApplicationEngineEnvironmentReloading.kt:310)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.access$launchModuleByName(ApplicationEngineEnvironmentReloading.kt:35)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:299)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:35)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartup(ApplicationEngineEnvironmentReloading.kt:317)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.instantiateAndConfigureApplication(ApplicationEngineEnvironmentReloading.kt:297)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.createApplication(ApplicationEngineEnvironmentReloading.kt:138)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.start(ApplicationEngineEnvironmentReloading.kt:270)
at io.ktor.server.cio.CIOApplicationEngine$serverJob$1$2.invokeSuspend(CIOApplicationEngine.kt:62)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Caused by: java.lang.NoSuchMethodError: 'kotlinx.serialization.json.Json kotlinx.serialization.json.JsonKt.Json$default(kotlinx.serialization.json.Json, kotlin.jvm.functions.Function1, int, java.lang.Object)'
at io.ktor.serialization.JsonSupportKt.<clinit>(JsonSupport.kt:29)
at ExampleApplicationKt$module$1.invoke(ExampleApplication.kt:10)
at ExampleApplicationKt$module$1.invoke(ExampleApplication.kt:9)
at io.ktor.features.ContentNegotiation$Feature.install(ContentNegotiation.kt:104)
at io.ktor.features.ContentNegotiation$Feature.install(ContentNegotiation.kt:97)
at io.ktor.application.ApplicationFeatureKt.install(ApplicationFeature.kt:68)
at ExampleApplicationKt.module(ExampleApplication.kt:9)
... 30 more
openapi-generator version
Tried 5.1.1 and 5.2.0-SNAPSHOT.
I'm trying it first time, so I don't know if it's a regression.
OpenAPI declaration file content or url
Irrelevant - the bug does not depend on the provided OpenAPI declaration. It manifests itself even if I remove all generated Kotlin code and leave only build.gradle
+ other build system config files.
Generation Details
I used this command:
java -jar openapi-generator-cli.jar generate \
--generator-name kotlin \
--input-spec https://petstore.swagger.io/v2/swagger.json \
--library multiplatform \
--output generated-client
Steps to reproduce
See the minimal project: https://github.com/krzema12/openapi-kotlin-multiplatform-issue-repro
Clone it and run ./gradlew run
.
Related issues/PRs
This commit updates Kotlin version and related stuff, but in a different place: https://github.com/OpenAPITools/openapi-generator/commit/173a349e04880b4fbf27224a9a8e6632f528d681
Suggest a fix
Between Kotlin versions (1.3.x - 1.5.x), a lot has happened with kotlinx.serialization library, including backward-incompatible changes. Chances are there is some incompatibility which is not caught in compile time.
Assuming that the issue is caused primarily by including incorrect version(s) of some Kotlin-related libraries, fixing this issue needs to start from bumping the version(s) in https://github.com/OpenAPITools/openapi-generator/blob/173a349e04880b4fbf27224a9a8e6632f528d681/modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/build.gradle.mustache and then adjusting the generated code accordingly.