quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.8k stars 2.68k forks source link

SmallRye GraphQL conflict with same enum names in different models #12402

Closed miador closed 4 years ago

miador commented 4 years ago

SmallRye GraphQL cannot differentiate same enum names in different models from version 1.6.0 to 1.8.1. We have GraphQL API for banking. We have separate models i.e Accounts and Balances. In Accounts we have an enum called Type and we have enum with same name Type in Balances.

The expected behavior is to see they're working fine as in previous versions. The quarkus version was 1.5.2 for this apps and we decide to update the quarkus and plug-in versions. In the all versions after 1.5.2, the problem is same. In 1.5.2, it perfectly works without having conflict even if we have same enum name in different models.

Actual behavior The data is stored in Neo4j and when we run the application, it works fine with accounts. But when running the Balances, it gives the following stacktrace:

2020-09-29 18:51:46,311 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:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at io.quarkus.runner.bootstrap.StartupActionImpl$3.run(StartupActionImpl.java:134)
        at java.base/java.lang.Thread.run(Thread.java:834)
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:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at java.base/java.lang.Class.newInstance(Class.java:584)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:60)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:38)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:106)
        at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:29)
        ... 6 more
Caused by: java.lang.RuntimeException: Failed to start quarkus
        at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:287)
        ... 15 more
Caused by: graphql.AssertException: type can't be null
        at graphql.Assert.assertNotNull(Assert.java:16)
        at graphql.schema.GraphQLFieldDefinition.<init>(GraphQLFieldDefinition.java:85)
        at graphql.schema.GraphQLFieldDefinition$Builder.build(GraphQLFieldDefinition.java:473)
        at io.smallrye.graphql.bootstrap.Bootstrap.createGraphQLFieldDefinitionFromField(Bootstrap.java:399)
        at io.smallrye.graphql.bootstrap.Bootstrap.createGraphQLFieldDefinitionsFromFields(Bootstrap.java:386)
        at io.smallrye.graphql.bootstrap.Bootstrap.createGraphQLObjectType(Bootstrap.java:284)
        at io.smallrye.graphql.bootstrap.Bootstrap.createGraphQLObjectTypes(Bootstrap.java:271)
        at io.smallrye.graphql.bootstrap.Bootstrap.generateGraphQLSchema(Bootstrap.java:123)
        at io.smallrye.graphql.bootstrap.Bootstrap.bootstrap(Bootstrap.java:103)
        at io.smallrye.graphql.cdi.producer.GraphQLProducer.initialize(GraphQLProducer.java:41)
        at io.smallrye.graphql.cdi.producer.GraphQLProducer.initialize(GraphQLProducer.java:37)
        at io.smallrye.graphql.cdi.producer.GraphQLProducer_ClientProxy.initialize(GraphQLProducer_ClientProxy.zig:185)
        at io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLRecorder.createExecutionService(SmallRyeGraphQLRecorder.java:24)
        at io.quarkus.deployment.steps.SmallRyeGraphQLProcessor$buildExecutionService-1556698146.deploy_2(SmallRyeGraphQLProcessor$buildExecutionService-1556698146.zig:5278)
        at io.quarkus.deployment.steps.SmallRyeGraphQLProcessor$buildExecutionService-1556698146.deploy(SmallRyeGraphQLProcessor$buildExecutionService-1556698146.zig:50)
        at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:267)

To Reproduce Steps to reproduce the behavior:

  1. Create 2 separate models.
  2. Have an enum type in both models with same enum name.(i.e enum Type in Accounts and Balances)
  3. Run it in debug mode, put the breakpoint on line 85 in GraphQLFieldDefinition.java and see the hitting type can't be null on same enum name.

Environment (please complete the following information):

Additional context If you really want to see that's the reason, you can simply create other models as well and have same enum name. It will hit on that and will say type can't be null

Regards! Yusuf

quarkusbot commented 4 years ago

/cc @phillip-kruger, @jmartisk /cc @kenfinnigan, @phillip-kruger, @jmartisk, @radcortez, @Ladicek

gsmet commented 4 years ago

Please create a small Maven reproducer, it's really far easier for us to reproduce issues that way.

Thanks!

phillip-kruger commented 4 years ago

@miador - yes a reproducer will help. As a workaround you can try and give the types unique names using the Enum annotation: Something like:

@Enum("AccountType") and @Enum("BalanceType") (as a class level annotation on the enum)

see https://download.eclipse.org/microprofile/microprofile-graphql-1.0.2/microprofile-graphql.html#enums