smallrye / smallrye-graphql

Implementation for MicroProfile GraphQL
Apache License 2.0
158 stars 91 forks source link

Discrepancy in handling @Source Methods between java and kotlin #2150

Open robp94 opened 1 month ago

robp94 commented 1 month ago

Having a @Source Method with both a List and non List Variant fails with Kotlin, while the same works in java. Kotlin worked until quarkus 3.8.5. Removing one of the methods solves the problem.

Example:

    fun inner(@Source middle: Middle): Inner {
        return Inner("inner")
    }

    fun inner(@Source middle: List<Middle>): List<Inner> {
        return listOf(Inner("inner"))
    }

Exception on build:

[ERROR]         [error]: Build step io.quarkus.smallrye.graphql.deployment.SmallRyeGraphQLProcessor#buildExecutionService threw an exception: java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
[ERROR]         at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)
[ERROR]         at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
[ERROR]         at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
[ERROR]         at java.base/java.util.Objects.checkIndex(Objects.java:385)
[ERROR]         at java.base/java.util.ArrayList.get(ArrayList.java:427)
[ERROR]         at io.smallrye.graphql.schema.creator.OperationCreator.compareJavaAndKotlinType(OperationCreator.java:219)
[ERROR]         at io.smallrye.graphql.schema.creator.OperationCreator.compareParameterLists(OperationCreator.java:192)
[ERROR]         at io.smallrye.graphql.schema.creator.OperationCreator.lambda$checkWrappedTypeKotlinNullability$1(OperationCreator.java:132)
[ERROR]         at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178)
[ERROR]         at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
[ERROR]         at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1685)
[ERROR]         at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
[ERROR]         at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
[ERROR]         at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
[ERROR]         at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
[ERROR]         at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
[ERROR]         at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
[ERROR]         at java.base/java.util.stream.ReferencePipeline.findAny(ReferencePipeline.java:652)
[ERROR]         at io.smallrye.graphql.schema.creator.OperationCreator.checkWrappedTypeKotlinNullability(OperationCreator.java:133)
[ERROR]         at io.smallrye.graphql.schema.creator.OperationCreator.createOperation(OperationCreator.java:112)
[ERROR]         at io.smallrye.graphql.schema.creator.type.AbstractCreator.toOperations(AbstractCreator.java:128)
[ERROR]         at io.smallrye.graphql.schema.creator.type.AbstractCreator.addOperations(AbstractCreator.java:117)
[ERROR]         at io.smallrye.graphql.schema.creator.type.AbstractCreator.create(AbstractCreator.java:75)
[ERROR]         at io.smallrye.graphql.schema.creator.type.TypeCreator.create(TypeCreator.java:31)
[ERROR]         at io.smallrye.graphql.schema.creator.type.AbstractCreator.create(AbstractCreator.java:31)
[ERROR]         at io.smallrye.graphql.schema.SchemaBuilder.createAndAddToSchema(SchemaBuilder.java:336)
[ERROR]         at io.smallrye.graphql.schema.SchemaBuilder.addTypesToSchema(SchemaBuilder.java:233)
[ERROR]         at io.smallrye.graphql.schema.SchemaBuilder.generateSchema(SchemaBuilder.java:154)
[ERROR]         at io.smallrye.graphql.schema.SchemaBuilder.build(SchemaBuilder.java:104)
[ERROR]         at io.quarkus.smallrye.graphql.deployment.SmallRyeGraphQLProcessor.buildExecutionService(SmallRyeGraphQLProcessor.java:324)
[ERROR]         at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
[ERROR]         at java.base/java.lang.reflect.Method.invoke(Method.java:580)
[ERROR]         at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:849)
[ERROR]         at io.quarkus.builder.BuildContext.run(BuildContext.java:256)
[ERROR]         at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
[ERROR]         at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2516)
[ERROR]         at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2495)
[ERROR]         at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1521)
[ERROR]         at java.base/java.lang.Thread.run(Thread.java:1583)
[ERROR]         at org.jboss.threads.JBossThread.run(JBossThread.java:483)

code-with-quarkus-source-list-kotlin.zip

phillip-kruger commented 1 month ago

We can look at why this happens (@jmartisk) but also know that the method with the non-list will never be called by the graphql framework if there exist a list one, so effectively you can remove the @Source annotation (or the whole method if no-one else is using it). This still support single queries, but the list (with one item) method will be called.