Generated GQL client causes `kotlinx.serialization` compiler recursion error
Library Version Kotlin Version: 1.8.0 (also tested 1.7.20)
id("com.expediagroup.graphql") version "6.3.3"
...
implementation("com.expediagroup:graphql-kotlin-spring-client:6.3.3") {
exclude("com.expediagroup", "graphql-kotlin-client-jackson")
}
implementation("com.expediagroup:graphql-kotlin-client-serialization:6.3.3")
Describe the bug
After switching from Jackson to kotlinx.serialization the generated code no longer compiles. It fails in the step kotlinCompile with the exception.
org.jetbrains.kotlin.util.KotlinFrontEndException: Front-end Internal error: Failed to analyze declaration Variables
File being compiled: (30,3) in /Users/christian/dev/doms-ecom-integration/build/generated/source/graphql/main/test/CreateFulfilmentOption.kt
The root cause java.lang.AssertionError was thrown at: org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor.getModality(LazyClassDescriptor.java:584)
at org.jetbrains.kotlin.resolve.ExceptionWrappingKtVisitorVoid.visitDeclaration(ExceptionWrappingKtVisitorVoid.kt:43)
at org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:461)
at org.jetbrains.kotlin.psi.KtVisitorVoid.visitDeclaration(KtVisitorVoid.java:21)
at org.jetbrains.kotlin.psi.KtVisitor.visitNamedDeclaration(KtVisitor.java:406)
...
Caused by: java.lang.AssertionError: Recursion detected in a lazy value under LockBasedStorageManager@756f0f2d (TopDownAnalyzer for JVM)
at org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor.getModality(LazyClassDescriptor.java:584)
at org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializationUtilKt.getShouldHaveGeneratedSerializer(KSerializationUtil.kt:138)
at org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationResolveExtension.generateSyntheticClasses(SerializationResolveExtension.kt:78)
The generated code looks like this
@Generated
@Serializable
public class CreateFulfilmentOption(
public override val variables: CreateFulfilmentOption.Variables,
) : GraphQLClientRequest<CreateFulfilmentOption.Result> {
@Required
public override val query: String = CREATE_FULFILMENT_OPTION
@Required
public override val operationName: String = "CreateFulfilmentOption"
public override fun responseType(): KClass<CreateFulfilmentOption.Result> =
CreateFulfilmentOption.Result::class
@Generated
@Serializable
public data class Variables(
public val input: CreateFulfilmentOptionInput,
public val executionMode: ExecutionMode? = null,
)
@Generated
@Serializable
public data class Result(
public val createFulfilmentOption: FulfilmentOption? = null,
)
}
The problem seems to be related to the nested class Result. After moving it outside of CreateFulfilmentOption the error is gone
To Reproduce
Generate client code with kotlinx serialiser and try to compile with the described version.
Expected behavior The generated code compiles
@holzerch have you found a workaround for this? I've tried playing with a lot of versions but have not come up with a winning combination yet
@holzerch have you found a workaround for this? I've tried playing with a lot of versions but have not come up with a winning combination yet
sadly no. I went back to Jackson and really wondering how this can work for anyone else
Hello 👋
graphql-kotlin v6 is using Kotlin v1.6.21 and kotlinx.serialization v1.3.2 (link).
Next major (v7 alpha is out) is targeting Kotlin v1.7.21 and kotlinx.serialization v1.4.1 (link).
Thanks, Derek
Hey Derek, thanks for the explanation. I wasn't aware of that. Since I don't want to downgrade my Kotlin version to 1.6, I tried the v7 alpha version sadly without success. The problem is still the same, which is no surprise since the generated code looks the same.
Can you provide a link to a repository that reproduces this issue?
Tests within the repo seems to be fine
@holzerch v7 alpha version does not contain the changes @dariuszkuc mentioned
Kotlin v1.7.21 and kotlinx.serialization v1.4.1 (link)
we can probably release another alpha or you can publish to your local repository and try it.
@samuelAndalon could you please release the current state of the v7 as another alpha?
Can you provide a link to a repository that reproduces this issue?
@dariuszkuc Here is a repo to reproduce the error. Just run ./gradlew build
https://github.com/holzerch/gql-client-kotlin-serialization-bug
It is just a plain Spring Initializr project with added dummy schema, query and client generation
Hello 👋
It appears that this is actually a compiler plugin issue (https://youtrack.jetbrains.com/issue/KT-39491). Per spring docs it should be possible to use kotlinx-serialization but if I apply Kotlin Spring plugin it blows up for me.
Removing Kotlin Spring plugin (but keeping serialization and Spring Boot plugins) seems to work.
Thanks, Derek
Thanks for digging up the root cause @dariuszkuc I just want to point out that you can workaround the problem by changing the structure of the generated code a little bit as I mentioned in the initial issue statement.
The problem seems to be related to the nested class Result. After moving it outside of the parent the error is gone
Since this is breaking change maybe it would be something for version 7?