Skip to content

Commit 0205d7f

Browse files
author
etienne-sf
committed
Issues #184 and #198: error with custom class out of plugin classpath
1 parent 8ad0f46 commit 0205d7f

File tree

30 files changed

+1214
-142
lines changed

30 files changed

+1214
-142
lines changed

CHANGELOG.md

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,11 @@
11

2+
# 1.18.12
23

3-
# 2.0
4-
5-
Change of some plugin parameters value (please read either [[Client migration from 1.x to 2.x|client_migrate_1-x_to_2-x]] or [[Server migration from 1.x to 2.x|server_migrate_1-x_to_2-x]] for more information) changed of default value:
6-
* copyRuntimeSources: false _(both client and server mode)_
7-
* generateBatchLoaderEnvironment: true _(server only)_
8-
* generateDeprecatedRequestResponse: false _(client only)_
9-
* skipGenerationIfSchemaHasNotChanged: true _(both client and server mode)_
10-
It was initially planned to force their value to the new default valye. But this would have too much impact on the existing code. Changing the default value allows 'old' users to minimize the impact when switching to the 2.0 version, while new user will use cleaner code.
11-
12-
13-
# 2.0RC1
14-
15-
Release Candidate version for the 2.x versions.
16-
17-
Main changes:
18-
* Based on [spring-graphql](https://spring.io/projects/spring-graphql)
19-
* Upgrade of dependencies, based on [spring-boot 2.7.10](https://docs.spring.io/spring-boot/docs/2.7.10/reference/html/)
20-
* Needs JDK 17 to be build, but the generated artifact is compatible with Java 8
21-
* Compatibility with Spring Boot 3.
22-
* For a sample of this, you can check the [graphql-maven-plugin-samples-Forum-client](https://github.com/graphql-java-generator/graphql-maven-plugin-project/tree/master_2.x/graphql-maven-plugin-samples/graphql-maven-plugin-samples-Forum-client) and the [graphql-maven-plugin-samples-Forum-server](https://github.com/graphql-java-generator/graphql-maven-plugin-project/tree/master_2.x/graphql-maven-plugin-samples/graphql-maven-plugin-samples-Forum-server) samples that are part of the build.
23-
* __gradle plugin__: The id changed from `com.graphql_java_generator.graphql-gradle-plugin` to `com.graphql-java-generator.graphql-gradle-plugin`
24-
25-
You can check these pages for more information on how to migrate from 1.x versions:
26-
* [[Client migration from 1.x to 2.x|client_migrate_1-x_to_2-x]]
27-
* [[Server migration from 1.x to 2.x|server_migrate_1-x_to_2-x]]
28-
29-
Know issues:
30-
* All builds for servers should be executed with a clean (_mvn clean install_ or _gradlew clean build_), otherwise the GraphQL schema available at runtime becomes invalid. The server won't start.
31-
* For Spring 3, in client mode, copyRuntimeSources should be manually to false, to avoid compilation errors
4+
Client and server modes:
5+
* Correction of issues #184 and #198: error with custom scalars, when the custom scalar's class is not in the plugin's classpath
326

7+
Client mode:
8+
* Issue 199: the generated code would not compile if the GraphQL schema is too big
339

3410

3511
# 1.18.11

graphql-java-common-runtime/src/main/java/com/graphql_java_generator/util/GraphqlUtils.java

Lines changed: 160 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,159 @@ public GraphqlUtils() {
127127
javaKeywords.add("void");
128128
javaKeywords.add("volatile");
129129
javaKeywords.add("while");
130+
this.javaKeywords.add("abstract");
131+
this.javaKeywords.add("assert");
132+
this.javaKeywords.add("boolean");
133+
this.javaKeywords.add("break");
134+
this.javaKeywords.add("byte");
135+
this.javaKeywords.add("case");
136+
this.javaKeywords.add("catch");
137+
this.javaKeywords.add("char");
138+
this.javaKeywords.add("class");
139+
this.javaKeywords.add("const");
140+
this.javaKeywords.add("continue");
141+
this.javaKeywords.add("default");
142+
this.javaKeywords.add("do");
143+
this.javaKeywords.add("double");
144+
this.javaKeywords.add("else");
145+
this.javaKeywords.add("enum");
146+
this.javaKeywords.add("extends");
147+
this.javaKeywords.add("final");
148+
this.javaKeywords.add("finally");
149+
this.javaKeywords.add("float");
150+
this.javaKeywords.add("for");
151+
this.javaKeywords.add("goto");
152+
this.javaKeywords.add("if");
153+
this.javaKeywords.add("implements");
154+
this.javaKeywords.add("import");
155+
this.javaKeywords.add("instanceof");
156+
this.javaKeywords.add("int");
157+
this.javaKeywords.add("interface");
158+
this.javaKeywords.add("long");
159+
this.javaKeywords.add("native");
160+
this.javaKeywords.add("new");
161+
this.javaKeywords.add("null");
162+
this.javaKeywords.add("package");
163+
this.javaKeywords.add("private");
164+
this.javaKeywords.add("protected");
165+
this.javaKeywords.add("public");
166+
this.javaKeywords.add("return");
167+
this.javaKeywords.add("short");
168+
this.javaKeywords.add("static");
169+
this.javaKeywords.add("strictfp");
170+
this.javaKeywords.add("super");
171+
this.javaKeywords.add("switch");
172+
this.javaKeywords.add("synchronized");
173+
this.javaKeywords.add("this");
174+
this.javaKeywords.add("throw");
175+
this.javaKeywords.add("throws");
176+
this.javaKeywords.add("transient");
177+
this.javaKeywords.add("try");
178+
this.javaKeywords.add("void");
179+
this.javaKeywords.add("volatile");
180+
this.javaKeywords.add("while");
181+
this.javaKeywords.add("abstract");
182+
this.javaKeywords.add("assert");
183+
this.javaKeywords.add("boolean");
184+
this.javaKeywords.add("break");
185+
this.javaKeywords.add("byte");
186+
this.javaKeywords.add("case");
187+
this.javaKeywords.add("catch");
188+
this.javaKeywords.add("char");
189+
this.javaKeywords.add("class");
190+
this.javaKeywords.add("const");
191+
this.javaKeywords.add("continue");
192+
this.javaKeywords.add("default");
193+
this.javaKeywords.add("do");
194+
this.javaKeywords.add("double");
195+
this.javaKeywords.add("else");
196+
this.javaKeywords.add("enum");
197+
this.javaKeywords.add("extends");
198+
this.javaKeywords.add("final");
199+
this.javaKeywords.add("finally");
200+
this.javaKeywords.add("float");
201+
this.javaKeywords.add("for");
202+
this.javaKeywords.add("goto");
203+
this.javaKeywords.add("if");
204+
this.javaKeywords.add("implements");
205+
this.javaKeywords.add("import");
206+
this.javaKeywords.add("instanceof");
207+
this.javaKeywords.add("int");
208+
this.javaKeywords.add("interface");
209+
this.javaKeywords.add("long");
210+
this.javaKeywords.add("native");
211+
this.javaKeywords.add("new");
212+
this.javaKeywords.add("null");
213+
this.javaKeywords.add("package");
214+
this.javaKeywords.add("private");
215+
this.javaKeywords.add("protected");
216+
this.javaKeywords.add("public");
217+
this.javaKeywords.add("return");
218+
this.javaKeywords.add("short");
219+
this.javaKeywords.add("static");
220+
this.javaKeywords.add("strictfp");
221+
this.javaKeywords.add("super");
222+
this.javaKeywords.add("switch");
223+
this.javaKeywords.add("synchronized");
224+
this.javaKeywords.add("this");
225+
this.javaKeywords.add("throw");
226+
this.javaKeywords.add("throws");
227+
this.javaKeywords.add("transient");
228+
this.javaKeywords.add("try");
229+
this.javaKeywords.add("void");
230+
this.javaKeywords.add("volatile");
231+
this.javaKeywords.add("while");
232+
this.javaKeywords.add("abstract");
233+
this.javaKeywords.add("assert");
234+
this.javaKeywords.add("boolean");
235+
this.javaKeywords.add("break");
236+
this.javaKeywords.add("byte");
237+
this.javaKeywords.add("case");
238+
this.javaKeywords.add("catch");
239+
this.javaKeywords.add("char");
240+
this.javaKeywords.add("class");
241+
this.javaKeywords.add("const");
242+
this.javaKeywords.add("continue");
243+
this.javaKeywords.add("default");
244+
this.javaKeywords.add("do");
245+
this.javaKeywords.add("double");
246+
this.javaKeywords.add("else");
247+
this.javaKeywords.add("enum");
248+
this.javaKeywords.add("extends");
249+
this.javaKeywords.add("final");
250+
this.javaKeywords.add("finally");
251+
this.javaKeywords.add("float");
252+
this.javaKeywords.add("for");
253+
this.javaKeywords.add("goto");
254+
this.javaKeywords.add("if");
255+
this.javaKeywords.add("implements");
256+
this.javaKeywords.add("import");
257+
this.javaKeywords.add("instanceof");
258+
this.javaKeywords.add("int");
259+
this.javaKeywords.add("interface");
260+
this.javaKeywords.add("long");
261+
this.javaKeywords.add("native");
262+
this.javaKeywords.add("new");
263+
this.javaKeywords.add("null");
264+
this.javaKeywords.add("package");
265+
this.javaKeywords.add("private");
266+
this.javaKeywords.add("protected");
267+
this.javaKeywords.add("public");
268+
this.javaKeywords.add("return");
269+
this.javaKeywords.add("short");
270+
this.javaKeywords.add("static");
271+
this.javaKeywords.add("strictfp");
272+
this.javaKeywords.add("super");
273+
this.javaKeywords.add("switch");
274+
this.javaKeywords.add("synchronized");
275+
this.javaKeywords.add("this");
276+
this.javaKeywords.add("throw");
277+
this.javaKeywords.add("throws");
278+
this.javaKeywords.add("transient");
279+
this.javaKeywords.add("try");
280+
this.javaKeywords.add("void");
281+
this.javaKeywords.add("volatile");
282+
this.javaKeywords.add("while");
130283
}
131284

132285
/**
@@ -141,17 +294,17 @@ public String getRuntimeVersion() {
141294
* Loads the runtime properties file, from the graphql-java-runtime.properties file.
142295
*/
143296
private Properties getProperties() {
144-
if (properties == null) {
145-
properties = new Properties();
297+
if (this.properties == null) {
298+
this.properties = new Properties();
146299
try (InputStream res = getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE)) {
147-
properties.load(res);
300+
this.properties.load(res);
148301
} catch (IOException e) {
149302
String msg = "Error while reading the '" + PROPERTIES_FILE + "' properties file: " + e.getMessage();
150303
logger.error(msg);
151304
throw new RuntimeException(msg, e);
152305
}
153306
}
154-
return properties;
307+
return this.properties;
155308
}
156309

157310
/**
@@ -919,7 +1072,7 @@ public String getJavaName(String name) {
9191072
* @return
9201073
*/
9211074
public boolean isJavaReservedWords(String name) {
922-
return javaKeywords.contains(name);
1075+
return this.javaKeywords.contains(name);
9231076
}
9241077

9251078
/**
@@ -968,14 +1121,8 @@ public String getPackageName(String classFullNameParam) {
9681121
return null; // No package for primitive types
9691122
}
9701123

971-
try {
972-
Class<?> cls = Class.forName(classFullName);
973-
return cls.getPackage().getName();
974-
} catch (ClassNotFoundException e) {
975-
throw new RuntimeException(
976-
"Could not find the package for the class '" + classFullNameParam + "', due to: " + e.getMessage(),
977-
e);
978-
}
1124+
int lstPointPosition = classFullName.lastIndexOf('.');
1125+
return classFullName.substring(0, lstPointPosition);
9791126
}
9801127

9811128
/**
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
*
3+
*/
4+
package com.generated.graphql.samples.customscalar;
5+
6+
/**
7+
* A class that override a String, to check custom scalars, where the Java type is not known of the plugin while
8+
* generating the code. As explained in the issues
9+
* <a href="https://github.com/graphql-java-generator/graphql-maven-plugin-project/issues/184">184</a> and
10+
* <a href="https://github.com/graphql-java-generator/graphql-maven-plugin-project/issues/198">198</a>, it would
11+
* generate an error.
12+
*
13+
* @author etienne-sf
14+
*
15+
*/
16+
public class CustomId {
17+
18+
final private String id;
19+
20+
public CustomId(String id) {
21+
this.id = id;
22+
}
23+
24+
public String getId() {
25+
return this.id;
26+
}
27+
28+
@Override
29+
public String toString() {
30+
return this.id;
31+
}
32+
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/**
2+
*
3+
*/
4+
package com.generated.graphql.samples.customscalar;
5+
6+
import graphql.language.StringValue;
7+
import graphql.schema.Coercing;
8+
import graphql.schema.CoercingParseLiteralException;
9+
import graphql.schema.CoercingParseValueException;
10+
import graphql.schema.CoercingSerializeException;
11+
import graphql.schema.GraphQLScalarType;
12+
13+
/**
14+
* A scalar to test the correction of the issues
15+
* <a href="https://github.com/graphql-java-generator/graphql-maven-plugin-project/issues/184">184</a> and
16+
* <a href="https://github.com/graphql-java-generator/graphql-maven-plugin-project/issues/198">198</a>, it would
17+
* generate an error.
18+
*
19+
* @author etienne-sf
20+
*/
21+
public class GraphQLScalarTypeCustomId {
22+
23+
/**
24+
* Useless String scalar.<BR/>
25+
* It's used both as a sample, to be completed by a developper, according to his/her needs, and for the use in some
26+
* tests of the plugin logic (like in the Shopify sample, to handle (badly) various scalar as based on
27+
* strings).<BR/>
28+
* It's actually a bad management, as this custom scalars does nothing, but read basic strings. It's just for test.
29+
*/
30+
public static GraphQLScalarType CustomIdScalarType = GraphQLScalarType.newScalar().name("CustomId") //$NON-NLS-1$
31+
.description("Useless Custom Scalar for CustomId management").coercing( //$NON-NLS-1$
32+
33+
new Coercing<CustomId, String>() {
34+
35+
/**
36+
* Called to convert a Java object result of a DataFetcher to a valid runtime value for the
37+
* scalar type. <br/>
38+
* Note : Throw {@link graphql.schema.CoercingSerializeException} if there is fundamental
39+
* problem during serialisation, don't return null to indicate failure. <br/>
40+
* Note : You should not allow {@link java.lang.RuntimeException}s to come out of your serialize
41+
* method, but rather catch them and fire them as
42+
* {@link graphql.schema.CoercingSerializeException} instead as per the method contract.
43+
*
44+
* @param dataFetcherResult
45+
* is never null
46+
*
47+
* @return a serialized value which may be null.
48+
*
49+
* @throws graphql.schema.CoercingSerializeException
50+
* if value input can't be serialized
51+
*/
52+
@Override
53+
public String serialize(Object input) throws CoercingSerializeException {
54+
if (!(input instanceof CustomId)) {
55+
throw new CoercingSerializeException(
56+
"Can't parse the '" + input.toString() + "' to a String"); //$NON-NLS-1$ //$NON-NLS-2$
57+
} else {
58+
return input.toString();
59+
}
60+
}
61+
62+
/**
63+
* Called to resolve an input from a query variable into a Java object acceptable for the scalar
64+
* type. <br/>
65+
* Note : You should not allow {@link java.lang.RuntimeException}s to come out of your
66+
* parseValue method, but rather catch them and fire them as
67+
* {@link graphql.schema.CoercingParseValueException} instead as per the method contract.
68+
*
69+
* @param input
70+
* is never null
71+
*
72+
* @return a parsed value which is never null
73+
*
74+
* @throws graphql.schema.CoercingParseValueException
75+
* if value input can't be parsed
76+
*/
77+
@Override
78+
public CustomId parseValue(Object o) throws CoercingParseValueException {
79+
if (!(o instanceof String)) {
80+
throw new CoercingParseValueException(
81+
"Can't parse the '" + o.toString() + "' string to a String"); //$NON-NLS-1$ //$NON-NLS-2$
82+
} else {
83+
return new CustomId((String) o);
84+
}
85+
}
86+
87+
/**
88+
* Called during query validation to convert a query input AST node into a Java object
89+
* acceptable for the scalar type. The input object will be an instance of
90+
* {@link graphql.language.Value}. <br/>
91+
* Note : You should not allow {@link java.lang.RuntimeException}s to come out of your
92+
* parseLiteral method, but rather catch them and fire them as
93+
* {@link graphql.schema.CoercingParseLiteralException} instead as per the method contract.
94+
*
95+
* @param input
96+
* is never null
97+
*
98+
* @return a parsed value which is never null
99+
*
100+
* @throws graphql.schema.CoercingParseLiteralException
101+
* if input literal can't be parsed
102+
*/
103+
@Override
104+
public CustomId parseLiteral(Object o) throws CoercingParseLiteralException {
105+
// o is an AST, that is: an instance of a class that implements graphql.language.Value
106+
if (!(o instanceof StringValue)) {
107+
throw new CoercingParseValueException(
108+
"Can't parse the '" + o.toString() + "' string to a CustomId"); //$NON-NLS-1$ //$NON-NLS-2$
109+
} else {
110+
return new CustomId(((StringValue) o).getValue());
111+
}
112+
}
113+
})
114+
.build();
115+
}

0 commit comments

Comments
 (0)