Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use Panache Sort.Direction enum as method parameter for GraphQL query #36688

Open
mzuber opened this issue Oct 25, 2023 · 12 comments · May be fixed by #45298
Open

Unable to use Panache Sort.Direction enum as method parameter for GraphQL query #36688

mzuber opened this issue Oct 25, 2023 · 12 comments · May be fixed by #45298

Comments

@mzuber
Copy link
Contributor

mzuber commented Oct 25, 2023

Describe the bug

Using the Sort.Direction enum from the quarkus-hibernate-orm-panache extension as a method parameter for a GraphQL query defined with the quarkus-smallrye-graphql extension results in a startup failure when Quarkus tries to generate the schema of the exposed GraphQL API at application startup:

2023-10-25 14:30:49,999 WARN  [io.sma.gra.sch.cre.ReferenceCreator] (build-27) Class [io.quarkus.panache.common.Sort$Direction] is not indexed in Jandex. Can not scan Object Type, might not be mapped correctly. Kind = [CLASS]
2023-10-25 14:30:52,088 ERROR [io.qua.run.boo.StartupActionImpl] (Quarkus Main Thread) Error running Quarkus: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:113)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.ExceptionInInitializerError
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:70)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:124)
        at io.quarkus.runner.GeneratedMain.main(Unknown Source)
        ... 6 more
Caused by: java.lang.RuntimeException: Failed to start quarkus
        at io.quarkus.runner.ApplicationImpl.<clinit>(Unknown Source)
        ... 15 more
Caused by: graphql.AssertException: type Direction not found in schema
        at graphql.Assert.assertNotNull(Assert.java:17)
        at graphql.schema.GraphQLTypeResolvingVisitor.handleTypeReference(GraphQLTypeResolvingVisitor.java:49)
        at graphql.schema.GraphQLTypeResolvingVisitor.visitGraphQLTypeReference(GraphQLTypeResolvingVisitor.java:44)
        at graphql.schema.GraphQLTypeReference.accept(GraphQLTypeReference.java:62)
        at graphql.schema.SchemaTraverser$TraverserDelegateVisitor.enter(SchemaTraverser.java:109)
        at graphql.util.Traverser.traverse(Traverser.java:144)
        at graphql.schema.SchemaTraverser.doTraverse(SchemaTraverser.java:96)
        at graphql.schema.SchemaTraverser.depthFirst(SchemaTraverser.java:86)
        at graphql.schema.SchemaTraverser.depthFirst(SchemaTraverser.java:79)
        at graphql.schema.impl.SchemaUtil.replaceTypeReferences(SchemaUtil.java:105)
        at graphql.schema.GraphQLSchema$Builder.buildImpl(GraphQLSchema.java:938)
        at graphql.schema.GraphQLSchema$Builder.build(GraphQLSchema.java:904)
        at io.smallrye.graphql.bootstrap.Bootstrap.generateGraphQLSchema(Bootstrap.java:205)
        at io.smallrye.graphql.bootstrap.Bootstrap.bootstrap(Bootstrap.java:120)
        at io.smallrye.graphql.cdi.producer.GraphQLProducer.initialize(GraphQLProducer.java:52)
        at io.smallrye.graphql.cdi.producer.GraphQLProducer.initialize(GraphQLProducer.java:42)
        at io.smallrye.graphql.cdi.producer.GraphQLProducer.initialize(GraphQLProducer.java:32)
        at io.smallrye.graphql.cdi.producer.GraphQLProducer.initialize(GraphQLProducer.java:27)
        at io.smallrye.graphql.cdi.producer.GraphQLProducer_ClientProxy.initialize(Unknown Source)
        at io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLRecorder.createExecutionService(SmallRyeGraphQLRecorder.java:30)
        at io.quarkus.deployment.steps.SmallRyeGraphQLProcessor$buildExecutionService1691419614.deploy_7(Unknown Source)
        at io.quarkus.deployment.steps.SmallRyeGraphQLProcessor$buildExecutionService1691419614.deploy(Unknown Source)
        ... 16 more

Expected behavior

It is possible to use the Sort.Direction enum from the quarkus-hibernate-orm-panache as a method parameter for a GraphQL query.

Actual behavior

The quarkus-smallrye-graphql extension is unable to generate the schema of the exposed GraphQL API at application startup. Before the startup failure the warning Class [io.quarkus.panache.common.Sort$Direction] is not indexed in Jandex. Can not scan Object Type, might not be mapped correctly. Kind = [CLASS] is logged.

How to Reproduce?

In a Quarkus application using both the quarkus-hibernate-orm-panache and the quarkus-smallrye-graphql extension, define a GraphQL API using the Sort.Direction enum in a query definition:

@GraphQLApi
public class DemoResource {

    @Query("sortDirection")
    public String testPanacheSortDirectionEnum(Sort.Direction sortDirection) {
        return sortDirection.name();
    }
}

Output of uname -a or ver

No response

Output of java -version

openjdk version "17.0.7" 2023-04-18
OpenJDK Runtime Environment GraalVM CE 17.0.7+7.1 (build 17.0.7+7-jvmci-23.0-b12)
OpenJDK 64-Bit Server VM GraalVM CE 17.0.7+7.1 (build 17.0.7+7-jvmci-23.0-b12, mixed mode, sharing)

Quarkus version or git rev

3.4.3

Build tool (ie. output of mvnw --version or gradlew --version)

Gradle 8.3

Additional information

No response

@quarkus-bot
Copy link

quarkus-bot bot commented Oct 25, 2023

/cc @FroMage (panache), @jmartisk (graphql), @loicmathieu (panache), @phillip-kruger (graphql)

@jmartisk
Copy link
Contributor

When using classes from a dependency inside your graphql api, that dependency must be explicitly added to the index (with few exceptions)
Try adding this to your configuration

quarkus.index-dependency.panache.group-id=io.quarkus
quarkus.index-dependency.panache.artifact-id=quarkus-panache-common

@gsmet
Copy link
Member

gsmet commented Oct 26, 2023

It looks like an usage that could be common, I'm thinking we could add this enum to the index automatically.

@jmartisk
Copy link
Contributor

Yeah that makes sense I guess. @mskacelik will create a PR with that

@gsmet
Copy link
Member

gsmet commented Oct 26, 2023

@mskacelik the idea would be to use AdditionalIndexedClassesBuildItem in the Panache module.

@jmartisk
Copy link
Contributor

Why in Panache? Don't we want this in GraphQL, because it's most likely needed because of using it inside a GraphQL api?

@gsmet
Copy link
Member

gsmet commented Oct 26, 2023

I'm not sure if we have a capability for Panache but if we have one (or if you feel like adding one) then yes we can do it in Panache GraphQL.
But I think the class needs to be in the classpath to be added to the index so you need to check (and let's not check with a class loader call if we can avoid it).

@mzuber
Copy link
Contributor Author

mzuber commented Oct 26, 2023

When using classes from a dependency inside your graphql api, that dependency must be explicitly added to the index (with few exceptions) Try adding this to your configuration

quarkus.index-dependency.panache.group-id=io.quarkus
quarkus.index-dependency.panache.artifact-id=quarkus-panache-common

@jmartisk Thanks, this did the trick. Do you think there is value in adding a note to the SmallRye GraphQL guide on this? Happy to provide a PR.

@jmartisk
Copy link
Contributor

@gsmet There are capabilities for MONGODB_PANACHE and MONGODB_PANACHE_KOTLIN. I assume we could add separate capabilities for HIBERNATE_ORM_PANACHE, HIBERNATE_REACTIVE_PANACHE, HIBERNATE_ORM_PANACHE_KOTLIN, HIBERNATE_REACTIVE_PANACHE_KOTLIN and assume that if one of these six is present, then the class is present? We wanted to simply use QuarkusClassLoader.isClassPresentAtRuntime, is that bad?

@mzuber we could add something to additional notes (https://quarkus.io/guides/smallrye-graphql#additional-notes), probably not specifically about Panache, but more generally about using stuff from dependencies. This specific case might go away if we really start adding that enum into the index automatically.

@phillip-kruger
Copy link
Member

I don't think GraphQL needs this info ? Maybe the fix is the GraphQL just ignore the error ? If possible ?

@FroMage
Copy link
Member

FroMage commented Sep 16, 2024

Well, can it work with this error? What does the graphql look like if the error is ignored? If that causes the method to be ignored, that's probably not what we want, no?

gsmet added a commit to gsmet/quarkus that referenced this issue Dec 27, 2024
It's typically something that could be used as a parameter.

Fixes quarkusio#36688
@gsmet gsmet linked a pull request Dec 27, 2024 that will close this issue
@gsmet
Copy link
Member

gsmet commented Dec 27, 2024

I created #45298 as it's a quick win.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants