graphql-java-generator / graphql-maven-plugin-project

graphql-maven-plugin is a Maven Plugin for GraphQL, based on graphql-java. It accelerates the development for both the client and the server, by generating the Java code. It allows a quicker development when in contract-first approach, by avoiding to code the boilerplate code.
https://graphql-maven-plugin-project.graphql-java-generator.com
MIT License
115 stars 47 forks source link

"code too large" compilation error #199

Closed befc closed 9 months ago

befc commented 9 months ago

For a GraphQL spec file that has over 4000 classes, on any version of graphql-maven-plugin > 1.18.7. The generated code fails to compile due to:

[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /.../target/generated-sources/graphql-maven-plugin/.../GraphQLTypeMapping.java:[6,32] code too large

The root cause of the error is the method GraphQLTypeMapping.getJavaClass() exceeding the threshold of 65535 bytes

Is this a know issue? Is it possible to configure the plugin in a way that this won't happen?

Plugin configuration:

<plugin>
  <groupId>com.graphql-java-generator</groupId>
  <artifactId>graphql-maven-plugin</artifactId>
  <version>1.18.11</version>
  <executions>
    <execution>
      <goals>
        <goal>generateClientCode</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <!-- Let's configure the GraphQL Gradle Plugin: -->
    <!-- All available parameters are described here: -->
    <!-- https://graphql-maven-plugin-project.graphql-java-generator.com/graphql-maven-plugin/generateClientCode-mojo.html -->
    <packageName>...</packageName>
    <customScalars>
      <customScalar>
        <graphQLTypeName>Date</graphQLTypeName>
        <javaType>java.util.Date</javaType>
        <graphQLScalarTypeStaticField>com.graphql_java_generator.customscalars.GraphQLScalarTypeDate.Date</graphQLScalarTypeStaticField>
      </customScalar>
      <customScalar>
        <graphQLTypeName>JSON</graphQLTypeName>
        <javaType>java.lang.String</javaType>
        <graphQLScalarTypeStaticField>graphql.Scalars.GraphQLString</graphQLScalarTypeStaticField>
      </customScalar>
      <customScalar>
        <graphQLTypeName>MongoID</graphQLTypeName>
        <javaType>java.lang.String</javaType>
        <graphQLScalarTypeStaticField>graphql.Scalars.GraphQLString</graphQLScalarTypeStaticField>
      </customScalar>
      <customScalar>
        <graphQLTypeName>RegExpAsString</graphQLTypeName>
        <javaType>java.lang.String</javaType>
        <graphQLScalarTypeStaticField>graphql.Scalars.GraphQLString</graphQLScalarTypeStaticField>
      </customScalar>
      <customScalar>
        <graphQLTypeName>Upload</graphQLTypeName>
        <javaType>java.lang.String</javaType>
        <graphQLScalarTypeStaticField>graphql.Scalars.GraphQLString</graphQLScalarTypeStaticField>
      </customScalar>
    </customScalars>
    <!-- The parameters below change the 1.x default behavior. They are set to respect the behavior of the future 2.x versions -->
    <copyRuntimeSources>false</copyRuntimeSources>
    <generateDeprecatedRequestResponse>false</generateDeprecatedRequestResponse>
    <separateUtilityClasses>true</separateUtilityClasses>
    <skipGenerationIfSchemaHasNotChanged>true</skipGenerationIfSchemaHasNotChanged>
  </configuration>
</plugin>
etienne-sf commented 9 months ago

Hello,

I actually didn't test with such a large GraphQL schema.

The 2.x doesn't generate the big type mapping that exist in 1.x versions. Did you test the 2.2 version with your schema ?

Etienne

befc commented 9 months ago

Hi!

I get the same error in version 2.2. The generated GraphQLTypeMapping.java in 1.18.11 and 2.2 are equal.

For now, as I needed a quick fix, I updated to 1.18.11, and I'm applying a custom GraphQLTypeMapping.java file with the following change, in which every getJavaClass#() has 1000 case statements. I tried first to split the ~4400 in half but that was not enough.

    public static Class<?> getJavaClass(String typeName) {
        Class<?> javaClass;

        javaClass = getJavaClass1(typeName);
        if (javaClass != null) {
            return javaClass;
        }

        javaClass = getJavaClass2(typeName);
        if (javaClass != null) {
            return javaClass;
        }

        javaClass = getJavaClass3(typeName);
        if (javaClass != null) {
            return javaClass;
        }

        javaClass = getJavaClass4(typeName);
        if (javaClass != null) {
            return javaClass;
        }

        javaClass = getJavaClass5(typeName);
        if (javaClass != null) {
            return javaClass;
        }

        return null;
    }
etienne-sf commented 9 months ago

I just released a 2.3 version. I'll report part of it in the 1.x branch : I'll work on this issue before releasing a new version.

etienne-sf commented 9 months ago

If you're in a hurry, perhaps you can give a try to this template, instead of breaking down the switch that generates the compilation error:

package your.package;

import java.util.HashMap;
import java.util.Map;

public class GraphQLTypeMapping {

    private static Map<String, Class<?>> typeMap = new HashMap<>();

    static {
        typeMap.put("Type1", your.package.Type1.class);
        typeMap.put("Type2", your.package.Type2.class);
        ...
    }

    public static Class<?> getJavaClass(String typeName) {
        return typeMap.get(typeName);
    }

}
etienne-sf commented 9 months ago

Sorry, this leads again to the same kind of error.

etienne-sf commented 9 months ago

Hello,

It's corrected (not released) on the 2.x branch. I'll report it on the 1.x branch, along with another correction, and I'll release the 1.x new version.

befc commented 9 months ago

Thanks for the update

etienne-sf commented 9 months ago

The correction is available in versions 1.18.12 and 2.3.

FYI: this correction is quite simple. It's about generating a file (instead of java code), and read it at startup. But it was the one with the most unexpected traps in it... ! Please confirm that it works ok for you.

Regards Etienne