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

GraphQL schema is not generated when response type has Generics (Nested field) #1928

Closed
Somsss236 opened this issue Oct 4, 2023 · 2 comments · Fixed by #1931
Closed

GraphQL schema is not generated when response type has Generics (Nested field) #1928

Somsss236 opened this issue Oct 4, 2023 · 2 comments · Fixed by #1931

Comments

@Somsss236
Copy link

Hi,
I'm using the following code to generate GraphQL query. The nested field in response type has Generic type (Java Generics). Due to this schema is not generated automatically and getting exception graphql.AssertException: type Object not found in schema during startup.

Here is my Example Code:


package org.acme;
import org.eclipse.microprofile.graphql.DefaultValue;
import org.eclipse.microprofile.graphql.Description;
import org.eclipse.microprofile.graphql.GraphQLApi;
import org.eclipse.microprofile.graphql.Query;

/***
* An interface with Generic Type
*
* @param <T>
*/

	interface ResponseAttribute<T> {
		public T getValue();
	}

	class Greet implements ResponseAttribute<String> {
		String value;

		public Greet(String name) {
			this.value = value;
		}
 
		@Override
		public String getValue() {
			return "hello".concat(value);
		}
	}

	class ResponseComposite {
		Greet greet;

		public ResponseComposite(Greet greet) {
			this.greet = greet;
		}

		public Greet getGreet() {
			return this.greet;
		}

		public void setGreet(Greet greet) {
			this.greet = greet;
		}
	}

	@GraphQLApi
	public class HelloGraphQLResource {
		@Query
		@Description("Say hello")
		public ResponseComposite sayHello(String name) {
			ResponseComposite response = new ResponseComposite(new Greet(name));
			return null;
		}
	}


Exception:


2023-10-04 16:58:49,923 ERROR [io.qua.run.boo.StartupActionImpl] (Quarkus Main Thread) Error running Quarkus [Error Occurred After Shutdown]: 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:857)
Caused by: java.lang.ExceptionInInitializerError
        at java.base/java.lang.J9VMInternals.ensureError(J9VMInternals.java:206)
        at java.base/java.lang.J9VMInternals.recordInitializationFailure(J9VMInternals.java:195)
        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 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: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_1(Unknown Source)
        at io.quarkus.deployment.steps.SmallRyeGraphQLProcessor$buildExecutionService1691419614.deploy(Unknown Source)
        ... 16 more

Could you assist to me resolve the issue?

@vtcosta
Copy link

vtcosta commented Nov 13, 2023

I've extended this generics example a little bit to be used with mutations, like this:

public interface Attribute<T> {
    T getValue();
    void setValue(T value);
}

public class Greet implements Attribute<String> {
    private String value;

    public Greet() {}

    public Greet(String value) {
        this.value = value;
    }

    @Override
    public String getValue() {
        return this.value;
    }

    @Override
    public void setValue(String value) {
        this.value = value;
    }
}

    @Query
    public Greet sayHello(String value) {
        return new Greet(value);
    }

    @Mutation
    public boolean updateGreet(Greet greet) {
        return true;
    }

The example above seems to be working just fine. But if I change the parameterized type to Long, it will throw the same exception reported on this issue. Here is the example:

public class Greet implements Attribute<Long> {
    private Long value;

    public Greet() {}

    public Greet(Long value) {
        this.value = value;
    }

    @Override
    public Long getValue() {
        return this.value;
    }

    @Override
    public void setValue(Long value) {
        this.value = value;
    }
}

    @Query
    public Greet sayHello(Long value) {
        return new Greet(value);
    }

    @Mutation
    public boolean updateGreet(Greet greet) {
        return true;
    }

It seems this Long problem is specific for the mutation, because if I leave just the query, it works.

Should we reopen this issue? Or open a new one?

@jmartisk
Copy link
Member

Please open a new issue and we'll have a look

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

Successfully merging a pull request may close this issue.

3 participants