smallrye-graphql icon indicating copy to clipboard operation
smallrye-graphql copied to clipboard

[SchemaBuilder] generic methods overriding on TypeCreator

Open federico-s opened this issue 3 years ago • 6 comments

Hello everyone, my Quarkus application is not starting because of the following error:

Caused by: graphql.AssertException: type Object 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:97)
	at graphql.schema.GraphQLSchema$Builder.buildImpl(GraphQLSchema.java:928)
	at graphql.schema.GraphQLSchema$Builder.build(GraphQLSchema.java:894)
	at io.smallrye.graphql.bootstrap.Bootstrap.generateGraphQLSchema(Bootstrap.java:200)
	at io.smallrye.graphql.bootstrap.Bootstrap.bootstrap(Bootstrap.java:119)
	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_2(Unknown Source)
	at io.quarkus.deployment.steps.SmallRyeGraphQLProcessor$buildExecutionService1691419614.deploy(Unknown Source)
	... 17 more

I have the following classes:

public class MyDTO implements Identity<Long>{

    // fields...

    private Long referenceId;
    
    // getters/setters...
}


public interface Identity<T> {
    void setReferenceId(T referenceId);
    T getReferenceId();
}

Debugging the code, I see that in the method TypeCreator.addFields(...) it gets all the declared methods traversing the class hierarchy in a for loop. At the end of the for loop, for the class MyDto the variable allMethods contains two version of the getReferenceId method, one with Long and one with Object as return type. image

The method, then, puts all the fields in a map and so the Object-signed field overrides the Long-signed field, causing the error I get.

I don't know if the problem is the field overriding or the "type Object not found in schema" exception itself.

Could you please provide some support? I'm using version 1.9.3.

federico-s avatar Mar 01 '23 19:03 federico-s

Same problem in my project.

vitomanu96 avatar Mar 01 '23 20:03 vitomanu96

It probably is the second Object that gives you the error. GraphQL do not know how to map object to the schema. You can try and provide an mapper with @AdaptWith

phillip-kruger avatar Mar 01 '23 22:03 phillip-kruger

It probably is the second Object that gives you the error. GraphQL do not know how to map object to the schema. You can try and provide an mapper with @AdaptWith

I cannot manipulate the DTOs. Do you think this signature overriding for generic fields is a bug or do you think is a correct behaviour?

federico-s avatar Mar 02 '23 09:03 federico-s

How do you mean ? Can you provide a reproducer with comments in the classes that you can not change, and I can see if there is anything we can do.

phillip-kruger avatar Mar 02 '23 09:03 phillip-kruger

I'm facing the same issue when using Java records in conjunction with sealed interfaces. Here is my reproducer code - https://github.com/faskan/graphql. Appreciate any solution or workaround.

Stacktrace: graphql.AssertException: type CustomerProduct not found in schema at graphql.Assert.throwAssert(Assert.java:207) at graphql.Assert.assertNotNull(Assert.java:45) 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:111) at graphql.util.Traverser.traverse(Traverser.java:144) at graphql.schema.SchemaTraverser.doTraverse(SchemaTraverser.java:98) at graphql.schema.SchemaTraverser.depthFirst(SchemaTraverser.java:88) at graphql.schema.SchemaTraverser.depthFirst(SchemaTraverser.java:81) at graphql.schema.impl.SchemaUtil.replaceTypeReferences(SchemaUtil.java:105) at graphql.schema.GraphQLSchema$Builder.buildImpl(GraphQLSchema.java:878) at graphql.schema.GraphQLSchema$Builder.build(GraphQLSchema.java:841) at io.smallrye.graphql.bootstrap.Bootstrap.generateGraphQLSchema(Bootstrap.java:229) at io.smallrye.graphql.bootstrap.Bootstrap.bootstrap(Bootstrap.java:129) at io.smallrye.graphql.cdi.producer.GraphQLProducer.initialize(GraphQLProducer.java:59) at io.smallrye.graphql.cdi.producer.GraphQLProducer.initialize(GraphQLProducer.java:49) at io.smallrye.graphql.cdi.producer.GraphQLProducer.initialize(GraphQLProducer.java:39) at io.smallrye.graphql.cdi.producer.GraphQLProducer.initialize(GraphQLProducer.java:34) at io.smallrye.graphql.cdi.producer.GraphQLProducer_ClientProxy.initialize(Unknown Source) at io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLRecorder.createExecutionService(SmallRyeGraphQLRecorder.java:46) at io.quarkus.deployment.steps.SmallRyeGraphQLProcessor$buildExecutionService450434440.deploy_1(Unknown Source) at io.quarkus.deployment.steps.SmallRyeGraphQLProcessor$buildExecutionService450434440.deploy(Unknown Source) at io.quarkus.runner.ApplicationImpl.<clinit>(Unknown Source) at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method) at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1160) at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.ensureClassInitialized(MethodHandleAccessorFactory.java:300) at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.newConstructorAccessor(MethodHandleAccessorFactory.java:103) at java.base/jdk.internal.reflect.ReflectionFactory.newConstructorAccessor(ReflectionFactory.java:200) at java.base/java.lang.reflect.Constructor.acquireConstructorAccessor(Constructor.java:549) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486) 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) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:116) at java.base/java.lang.Thread.run(Thread.java:1583) Resulted in: io.quarkus.dev.appstate.ApplicationStartException: graphql.AssertException: type CustomerProduct not found in schema at io.quarkus.dev.appstate.ApplicationStateNotification.waitForApplicationStart(ApplicationStateNotification.java:63) at io.quarkus.runner.bootstrap.StartupActionImpl.runMainClass(StartupActionImpl.java:142) at io.quarkus.deployment.dev.IsolatedDevModeMain.restartApp(IsolatedDevModeMain.java:202) at io.quarkus.deployment.dev.IsolatedDevModeMain.restartCallback(IsolatedDevModeMain.java:183) at io.quarkus.deployment.dev.RuntimeUpdatesProcessor.doScan(RuntimeUpdatesProcessor.java:555) at io.quarkus.deployment.dev.RuntimeUpdatesProcessor.doScan(RuntimeUpdatesProcessor.java:455) at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$6.call(VertxHttpHotReplacementSetup.java:161) at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$6.call(VertxHttpHotReplacementSetup.java:148) at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$4(ContextImpl.java:192) at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:270) at io.vertx.core.impl.ContextImpl$1.execute(ContextImpl.java:221) at io.vertx.core.impl.WorkerTask.run(WorkerTask.java:56) at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18) at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675) at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1591) at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11) at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ... 1 more Resulted in: io.vertx.core.impl.NoStackTraceException

faskan avatar Dec 05 '24 16:12 faskan

@faskan I do not think your issue is related to this one. Please open a new issue with your reproducer. I think yours has got to do with the sealed interface.

phillip-kruger avatar Dec 05 '24 21:12 phillip-kruger