IndexOutOfBoundException when using directive annotations
cocobey73 opened this issue · comments
When I added a directive annotation to one of my additional classes (not the query class) the process fail with an index out of bound exception.
I would be happy if you give us a code example
Sure, here is an example. When I add the Upper annotation to a pojo field, I get this error
Exception in thread "main" java.lang.IllegalArgumentException: fromIndex(1) > toIndex(0) at java.util.ArrayList.subListRangeCheck(ArrayList.java:1014) at java.util.ArrayList.subList(ArrayList.java:1004) at java.util.Collections$UnmodifiableRandomAccessList.subList(Collections.java:1402) at graphql.schema.SchemaTransformer.moveUp(SchemaTransformer.java:363) at graphql.schema.SchemaTransformer.toRootNode(SchemaTransformer.java:217) at graphql.schema.SchemaTransformer.transform(SchemaTransformer.java:176) at graphql.annotations.AnnotationsSchemaCreator$Builder.build(AnnotationsSchemaCreator.java:271) at FailureExample.main(FailureExample.java:71)
Here is the sample code to get this error.
import graphql.ExecutionResult;
import graphql.GraphQL;
import graphql.GraphQLError;
import graphql.annotations.AnnotationsSchemaCreator;
import graphql.annotations.annotationTypes.GraphQLDeprecate;
import graphql.annotations.annotationTypes.GraphQLField;
import graphql.annotations.annotationTypes.GraphQLName;
import graphql.annotations.annotationTypes.directives.definition.DirectiveLocations;
import graphql.annotations.annotationTypes.directives.definition.GraphQLDirectiveDefinition;
import graphql.annotations.directives.AnnotationsDirectiveWiring;
import graphql.annotations.directives.AnnotationsWiringEnvironment;
import graphql.annotations.processor.util.CodeRegistryUtil;
import graphql.introspection.Introspection;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLSchema;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Map;
import java.util.stream.Collectors;
public class FailureExample {
public static class UpperWiring implements AnnotationsDirectiveWiring {
@Override
public GraphQLFieldDefinition onField(AnnotationsWiringEnvironment environment) {
GraphQLFieldDefinition field = (GraphQLFieldDefinition) environment.getElement();
boolean isActive = (boolean) environment.getDirective().getArgument("isActive").getValue();
CodeRegistryUtil.wrapDataFetcher(field, environment, (((dataFetchingEnvironment, value) -> {
if (value instanceof String && isActive) {
return ((String) value).toUpperCase();
}
return value;
})));
return field;
}
}
@GraphQLName("upper")
@GraphQLDirectiveDefinition(wiring = UpperWiring.class)
@DirectiveLocations({Introspection.DirectiveLocation.FIELD_DEFINITION})
@Retention(RetentionPolicy.RUNTIME)
@interface Upper {
@GraphQLName("isActive")
boolean isActive() default true;
}
public static class Query {
@GraphQLField
@GraphQLDeprecate
public static Pojo pojoQuery() {
return new Pojo();
}
}
public static class Pojo {
@GraphQLField
@GraphQLDeprecate
@Upper
public String pojoField() {
return "hello!";
}
}
public static void main(String... args) {
GraphQLSchema schema = AnnotationsSchemaCreator.newAnnotationsSchema()
.query(Query.class) // to create you query object
.additionalType(Pojo.class) // to create some additional type and add it to the schema
.setAlwaysPrettify(true) // to set the global prettifier of field names (removes get/set/is prefixes from names)
.directive(Upper.class) // to create a directive
.build();
GraphQL graphQL = GraphQL.newGraphQL(schema).build();
ExecutionResult result = graphQL.execute("{ pojoQuery { pojoField } }");
if (!result.getErrors().isEmpty()) {
throw new RuntimeException(result.getErrors().stream().map(GraphQLError::getMessage).collect(Collectors.joining()));
} else {
String pojoField = ((Map) result.<Map>getData().get("pojoQuery")).get("pojoField").toString();
if (!pojoField.equals("HELLO!")) {
throw new RuntimeException("Result was not upper cased -> " + pojoField);
}
}
}
}
My only dependency
dependencies {
implementation group: 'io.github.graphql-java', name: 'graphql-java-annotations', version: '8.0'
}
Im running on unix using jdk 1.8.0_241.
Let me know if you need more details, and appreciate the help.
If I delete the following line
.additionalType(Pojo.class) // to create some additional type and add it to the schema
The execution works without any exception.
I wonder why have you added this line of code?
The Pojo
class is referenced from the Query
class, therefore you do not need to add it as an AdditionalType. Only classes that are not referenced from the Query or his subtypes (such as graphql interface's implementations) should be inserted to the additional types of the schema.
Hope it helps.
Thanks for the explanation. That was not very clear, but it does work.