This is a security bugfix release containing only one PR: #3139
This adds a limit to the depth of grammar rules, to prevent stack overflow.
Full details can be found here: #3112
What's Changed
- Backported deep DOS parse attack into 17.x branch by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3139
Full Changelog: https://github.com/graphql-java/graphql-java/compare/v17.4...v17.5
This is a security bugfix release containing only one PR: #3144
This adds a limit to the depth of grammar rules, to prevent stack overflow.
Full details can be found here: #3112
What's Changed
- Add backport of rule depth rule to 18.x by @dondonz in https://github.com/graphql-java/graphql-java/pull/3144
Full Changelog: https://github.com/graphql-java/graphql-java/compare/v18.3...v18.4
This is a feature and bugfix release. There are no breaking changes in this release. This release continues to use Java 8.
Thanks to everyone in the community for helping us with this release. Thanks for your PRs, issues, and discussions!
Security fix
This release includes a security fix #3112 which adds a limit to the depth of grammar rules, to prevent stack overflow.
Highlights
#3095 improves resiliency to class loader problems with LambdaMetafactory
.
#3049 adds an extensions builder and merger.
Release policy
We have formalised our release schedule to give the community a better idea of when to expect releases, what will be contained within them, and when important fixes will be backported. See the full details at https://www.graphql-java.com/blog/release-policy
What's Changed
- docs: update badges for v20 release by @setchy in https://github.com/graphql-java/graphql-java/pull/3047
- Update FieldValidationInstrumentation.java by @kfwerf in https://github.com/graphql-java/graphql-java/pull/3066
- Update vulnerability reporting instructions by @dondonz in https://github.com/graphql-java/graphql-java/pull/3070
- Fix extend schema directives ANTLR rule by @dondonz in https://github.com/graphql-java/graphql-java/pull/3071
- Allow users to disable MultiSourceReader trackData through ParserOptions by @AntaresS in https://github.com/graphql-java/graphql-java/pull/3062
- Add missing getter and fix name consistency by @gnawf in https://github.com/graphql-java/graphql-java/pull/3073
- use toolchain to specify the java version by @andimarek in https://github.com/graphql-java/graphql-java/pull/3075
- Fix isNameChanged by @gnawf in https://github.com/graphql-java/graphql-java/pull/3076
- Update instrumentation example in documentation by @dondonz in https://github.com/graphql-java/graphql-java/pull/3078
- Reuse ExecutionStrategyInstrumentationContext.NOOP in DataLoaderDispatcherInstrumentation by @dfa1 in https://github.com/graphql-java/graphql-java/pull/3068
- Add missing this keyword for readability by @cookieMr in https://github.com/graphql-java/graphql-java/pull/3067
- defaulting the deprecated methods in Coercing by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3063
- Add missing detail by @gnawf in https://github.com/graphql-java/graphql-java/pull/3079
- Updating the JavaDoc http links by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3083
- An Extensions Builder by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3049
- Use ImmutableList.builderWithExpectedSize in ImmutableKit.mapAndDropNulls too by @dfa1 in https://github.com/graphql-java/graphql-java/pull/3081
- Resolve TypeReferences in schema applied directives by @kaqqao in https://github.com/graphql-java/graphql-java/pull/3054
- Remove sun.misc.* from MANIFEST.MF by @dondonz in https://github.com/graphql-java/graphql-java/pull/3091
- Replace javax nullable annotations with JetBrains equivalent by @dondonz in https://github.com/graphql-java/graphql-java/pull/3093
- Ensured that the MANIFEST.MF files is the first entry in the JAR File by @schaefa in https://github.com/graphql-java/graphql-java/pull/3097
- Fix type change and directive deletion problems in schema diffing by @gnawf in https://github.com/graphql-java/graphql-java/pull/3102
- Handle enum value rename by @gnawf in https://github.com/graphql-java/graphql-java/pull/3103
- Bugfix: do not use default operation name types if not included in schema definition block by @dondonz in https://github.com/graphql-java/graphql-java/pull/3088
- Adding ExtensionsBuilder in the graphql context by default by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3085
- Meta Lambda failures - make the code more resilient to class loader challenges by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3095
- Gracefully returning null in cases of UnresolvedTypeException by @ahmadizm in https://github.com/graphql-java/graphql-java/pull/3122
- Add dependabot configuration by @yeikel in https://github.com/graphql-java/graphql-java/pull/3115
- Bump org.jetbrains:annotations from 23.0.0 to 24.0.1 by @dependabot in https://github.com/graphql-java/graphql-java/pull/3125
- Remove unused dependencies by @dondonz in https://github.com/graphql-java/graphql-java/pull/3132
- Bump actions/checkout from 1 to 3 by @dependabot in https://github.com/graphql-java/graphql-java/pull/3126
- Bump google-github-actions/auth from 0.4.0 to 1.0.0 by @dependabot in https://github.com/graphql-java/graphql-java/pull/3129
- Bump org.codehaus.groovy:groovy from 3.0.9 to 3.0.16 by @dependabot in https://github.com/graphql-java/graphql-java/pull/3131
- Add manual stop on schema diffing algorithm by @gnawf in https://github.com/graphql-java/graphql-java/pull/3119
- Preventing stack overflow exceptions via limiting the depth of the parser rules by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3112
- UniqueObjectFieldName validation rule (#1806) by @ashatch in https://github.com/graphql-java/graphql-java/pull/3094
New Contributors
- @kfwerf made their first contribution in https://github.com/graphql-java/graphql-java/pull/3066
- @AntaresS made their first contribution in https://github.com/graphql-java/graphql-java/pull/3062
- @ahmadizm made their first contribution in https://github.com/graphql-java/graphql-java/pull/3122
- @yeikel made their first contribution in https://github.com/graphql-java/graphql-java/pull/3115
- @dependabot made their first contribution in https://github.com/graphql-java/graphql-java/pull/3125
- @ashatch made their first contribution in https://github.com/graphql-java/graphql-java/pull/3094
Full Changelog: https://github.com/graphql-java/graphql-java/compare/v20.0...v20.1
This is a security bugfix release containing PR #3133. This adds a limit to the depth of grammar rules, to prevent stack overflow. See the full details on the original PR: #3112.
This release also includes backported fixes to ensure MANIFEST.MF
is the first entry in the JAR file and removes sun.misc
from Import-Package
header. See the full details on the original PRs: #3091 and #3097.
What's Changed
- Backported the fix to remove sun.misc by @schaefa in https://github.com/graphql-java/graphql-java/pull/3099
- Backported #3112 into 19.x branch by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3133
Full Changelog: https://github.com/graphql-java/graphql-java/compare/v19.3...v19.4
We are pleased to announce the release of graphql-java 20.0. Special thanks to each of the 200+ contributors over the years, who have made this milestone possible.
Breaking changes
parseValue
coercion with JS reference implementation
Aligning We have made changes to String, Boolean, Float, and Int parseValue
coercion, to be consistent with the reference JS implementation. The key change is parseValue
is now stricter on accepted inputs.
- String
parseValue
now requires input is of typeString
. For example, a Number input123
or a Boolean inputtrue
will no longer be accepted. - Boolean
parseValue
now requires input is of typeBoolean
. For example, a String input"true"
will no longer be accepted. - Float
parseValue
now requires input is of typeNumber
. For example, a String input"3.14"
will no longer be accepted. - Int
parseValue
now requires input is of typeNumber
. For example, a String input"42"
will no longer be accepted.
String parseValue
changes: https://github.com/graphql-java/graphql-java/pull/3030
Boolean, Float, and Int parseValue
changes: https://github.com/graphql-java/graphql-java/pull/3042
JS reference implementation: https://github.com/graphql/graphql-js/blob/main/src/type/scalars.ts
Notable Changes
Record Like Property Fetching Support
We have now added the ability to find properties via "Record like" naming. We call it "Record like" based on Java 14 record
classes but in fact any class with a method named directly as the graphql field is named will work.
If you had this graphql object type declared
type Person {
name : String
address : String
}
then this Java record
would be supported for fetching values via the method names name()
and address()
public record Person (String name, String address)
and equally a non record class like this would also work
public class Person {
public String name() { return "Harry Potter"; }
public String address() { return "4 Privet Drive, Little Whinging"; }
}
We still have Java Bean (aka POJO) getter naming support like public String getName()
however now the "record like" name()
method will be used in preference and then the getName()
methods will be used if that's not present.
This means there is a new behavior if you had weird POJOs likes this
public class WeirdPerson {
public String name() { return "Harry Potter"; }
public String getName() { return "Tom Riddle"; }
}
A property fetch for name
will now return Harry Potter
and not Tom Riddle
as it previously would have.
This is a behavioral breaking change but on balance we think this behavior is the most correct going forward.
https://github.com/graphql-java/graphql-java/pull/2994
Improved Data Fetching
The PropertyDataFetcher
class is the most common data fetcher used in graphql-java. It uses Java reflection to get field values from objects based on field name.
This was logically the following
Method method = findMethod(fieldname);
method.invoke(object);
with the method lookup cached for performance reasons.
However there is mechanism in the JVM that provides even faster object reflective access.
See
https://wttech.blog/blog/2020/method-handles-and-lambda-metafactory/ https://www.optaplanner.org/blog/2018/01/09/JavaReflectionButMuchFaster.html
java.lang.invoke.LambdaMetafactory#metafactory
is an arcane mechanism that can be used to create virtual method lambdas that give fast access to call object methods. It turns out to be significantly faster that Java reflection and only marginally slower that directly invoking a method.
If you use PropertyDataFetcher
a lot (and chances are you do) then this should give improved performance.
The raw benchmarks are as follows
Java 8
Benchmark Mode Cnt Score Error Units
GetterAccessBenchmark.measureDirectAccess thrpt 15 81199548.105 ± 2717206.756 ops/s 0% slower (baseline)
GetterAccessBenchmark.measureLambdaAccess thrpt 15 79622345.446 ± 1183553.379 ops/s 2% slower
GetterAccessBenchmark.measureReflectionAccess thrpt 15 46102664.133 ± 4091595.318 ops/s 50% slower
Java 17
Benchmark Mode Cnt Score Error Units
GetterAccessBenchmark.measureDirectAccess thrpt 15 458411420.717 ± 34329506.990 ops/s 0%
GetterAccessBenchmark.measureLambdaAccess thrpt 15 334158880.091 ± 10666070.698 ops/s 27% slower
GetterAccessBenchmark.measureReflectionAccess thrpt 15 63181868.566 ± 3887367.970 ops/s 86% slower
It's worth noting that while the headline numbers here look impressive, the property fetching represents a smaller portion of what happens during graphql engine execution.
It probably won't be enough to keep Elon Musk happy but all performance improvements help and at scale they help the most.
Lightweight Data Fetchers
A DataFetcher
gets invoked with a calling environment context object called graphql.schema.DataFetchingEnvironment
. This is quite a rich object that contains all sorts of useful information.
However simple (aka trivial) data fetchers like PropertyDataFetcher
they don't need access to such a rich object. They just need the source object, the field name and the field type
To marginally help performance, we have introduced a graphql.schema.LightDataFetcher
for this use case
public interface LightDataFetcher<T> extends TrivialDataFetcher<T> {
T get(GraphQLFieldDefinition fieldDefinition, Object sourceObject, Supplier<DataFetchingEnvironment> environmentSupplier) throws Exception;
}
PropertyDataFetcher
implements this and hence this lowers the object allocation at scale (which reduces memory pressure) and will make the system marginally faster to fetch data.
https://github.com/graphql-java/graphql-java/pull/2953
Performance Improvements by avoid object allocations
We are always trying to wring out the most performance we can in graphql-java and so we reviewed our object allocations and found places where we can make savings.
These won't make dramatic performance savings but at scale all these things add up, reducing memory pressure and improving throughput marginally.
https://github.com/graphql-java/graphql-java/pull/2981 https://github.com/graphql-java/graphql-java/pull/2980 https://github.com/graphql-java/graphql-java/pull/2979
Locale is now available in Coercing and Parsing
The graphql.schema.Coercing
interface used by scalars can now receive a Locale
object that indicates the calling Locale
. The same is true for the parsing code via graphql.parser.ParserEnvironment#getLocale
A custom scalar implementation could use the locale to decide how to coerce values.
https://github.com/graphql-java/graphql-java/pull/2912 https://github.com/graphql-java/graphql-java/pull/2921
Easier ways to build common objects
We have added extra builders on the GraphQLError
, ErrorClassification
and ExecutionResult
interfaces that make it easier to build instances of these common classes.
https://github.com/graphql-java/graphql-java/pull/2939 https://github.com/graphql-java/graphql-java/pull/3011
The deprecated NextGen engine has been removed
The NextGen engine was an experimental feature that explored what it might take to build a new graphql engine. In many ways it was a success as it taught us a bunch of about graph algorithms and what works and what does not.
While it had some value, on balance it was not going to become production ready and so we deprecated it a while back and it has finally been removed.
https://github.com/graphql-java/graphql-java/pull/2923
What's Changed
- docs: update latest release badge to 19 by @setchy in https://github.com/graphql-java/graphql-java/pull/2918
- Fix printing directives when they contain something like a formatting… by @jmartisk in https://github.com/graphql-java/graphql-java/pull/2920
- Implement pretty printer by @felipe-gdr in https://github.com/graphql-java/graphql-java/pull/2894
- Fix snapshot badge by @dondonz in https://github.com/graphql-java/graphql-java/pull/2924
- Remove @fetch and nextgen engine by @dondonz in https://github.com/graphql-java/graphql-java/pull/2923
- Fix up field visibility doco example by @dondonz in https://github.com/graphql-java/graphql-java/pull/2927
- We can rename scalar types by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2928
- Add deprecation date to all deprecated methods and fields by @dondonz in https://github.com/graphql-java/graphql-java/pull/2929
- Fix field visibility bug with enum with enum args by @felipe-gdr in https://github.com/graphql-java/graphql-java/pull/2926
- Adding Locale to Coercing and hence ValueResolver by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2912
- Removes the deprecated execute methods from GraphQL by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2932
- Removing deprecated methods from tests - part 1 by @dondonz in https://github.com/graphql-java/graphql-java/pull/2930
- Reproduction of renaming scalars and applied directives bug by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2934
- Remove redundant NaN check, already handled in GraphqlFloatCoercing by @dondonz in https://github.com/graphql-java/graphql-java/pull/2936
- Diff counts are the same by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2935
- Change Instrumentation production implementations to use non deprecated methods by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2931
- Make parseValue nullable and update Coercing javadoc by @dondonz in https://github.com/graphql-java/graphql-java/pull/2938
- Cleaning up tests with deprecated usage: Part 2 by @dondonz in https://github.com/graphql-java/graphql-java/pull/2941
- Deprecation test cleanup: GraphQLFieldDefinition datafetcher builder by @dondonz in https://github.com/graphql-java/graphql-java/pull/2942
- Fix @skip definition is added twice to the GraphQLSchema when defined in sdl by @tinnou in https://github.com/graphql-java/graphql-java/pull/2940
- Added new builder to ExecutionResult by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2939
- Test cleanup: typeResolver builder on unions and interfaces, applied directive tests, and more by @dondonz in https://github.com/graphql-java/graphql-java/pull/2954
- Update GraphQL Instrospection Spec Link by @cookieMr in https://github.com/graphql-java/graphql-java/pull/2977
- Deprecation cleanout - programmatic schemas by @dondonz in https://github.com/graphql-java/graphql-java/pull/2974
- Avoid allocating a type resolve env if the type is already an object type by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2980
- Avoids allocating a copy of the field names set inside the ES by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2981
- Patch SchemaDiff to apply respective nullability change validation for input vs. output types by @bspeth in https://github.com/graphql-java/graphql-java/pull/2971
- Adding Locale to Parser by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2921
- Added workflow and gcp JS client library script with package json by @DiegoManzanarezx in https://github.com/graphql-java/graphql-java/pull/2889
- Add missing equals/hashcode methods to relay classes by @pgr0ss in https://github.com/graphql-java/graphql-java/pull/2988
- Float coercion tidy up by @dondonz in https://github.com/graphql-java/graphql-java/pull/2982
- Only run GCP tests on main graphql-java repo (skip on forks). by @folone in https://github.com/graphql-java/graphql-java/pull/2997
- Parameterized introspection queries by @MayCXC in https://github.com/graphql-java/graphql-java/pull/2993
- Update aQute builder version by @dondonz in https://github.com/graphql-java/graphql-java/pull/3002
- Avoid an allocation of a chained context in the most common case by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2979
- Polishing by @dfa1 in https://github.com/graphql-java/graphql-java/pull/3001
- Document the new IntrospectionQueryBuilder and tweaked it a little by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3003
- LambdaMetafactory support for property fetches by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2985
- SchemaGeneratorPostProcessing should be deprecated by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2999
- Fixes in TwitterBenchmark by @dfa1 in https://github.com/graphql-java/graphql-java/pull/3006
- Bugfix for SDL check if an Interface is implemented correctly by @andimarek in https://github.com/graphql-java/graphql-java/pull/3014
- Adds an error builder on GraphQLError by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3011
- TypeResolutionEnvironment#getLocalContext seems accidentally non-public by @kaqqao in https://github.com/graphql-java/graphql-java/pull/3021
- centralizing resource loading in BenchmarkUtils by @dfa1 in https://github.com/graphql-java/graphql-java/pull/3022
- Helper for getting fields based on object type name by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3016
- Avoiding some duplicated work in Async by @dfa1 in https://github.com/graphql-java/graphql-java/pull/3023
- Record like property access support by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2994
- Lightweight data fetchers by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2953
- Update ValidationError#toString to print the extentions field by @federicorispo in https://github.com/graphql-java/graphql-java/pull/3024
- Minor fixes by @dfa1 in https://github.com/graphql-java/graphql-java/pull/3029
- This makes sure every introspection type actually has a concrete data fetcher by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3004
- Make String parseValue coercion consistent with JS implementation & Gradle JCenter fix by @dondonz in https://github.com/graphql-java/graphql-java/pull/3030
- Adding new schema diffing capability (First step) by @andimarek in https://github.com/graphql-java/graphql-java/pull/2983
- chore: Remove unused imports and local variables by @federicorispo in https://github.com/graphql-java/graphql-java/pull/3034
- Testing I18n lookup by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3036
- Consider union containers when checking if type is referenced by @felipe-gdr in https://github.com/graphql-java/graphql-java/pull/3037
- master fix - use class loader on i18n by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3039
New Contributors
- @cookieMr made their first contribution in https://github.com/graphql-java/graphql-java/pull/2977
- @bspeth made their first contribution in https://github.com/graphql-java/graphql-java/pull/2971
- @DiegoManzanarezx made their first contribution in https://github.com/graphql-java/graphql-java/pull/2889
- @pgr0ss made their first contribution in https://github.com/graphql-java/graphql-java/pull/2988
- @MayCXC made their first contribution in https://github.com/graphql-java/graphql-java/pull/2993
- @federicorispo made their first contribution in https://github.com/graphql-java/graphql-java/pull/3024
Full Changelog: https://github.com/graphql-java/graphql-java/compare/v19.1...v20.0
The 19.3 bug fix release has been created
What's Changed
- 19.x fix - use class loader on i18n by @bbakerman in https://github.com/graphql-java/graphql-java/pull/3038
Full Changelog: https://github.com/graphql-java/graphql-java/compare/v19.2...v19.3
The 19.2 bug fix release has been created
What's Changed
- Stable fix for #2934 by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2943
- Stable port of Fix field visibility bug with enum with enum args (#2926) by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2944
- Stable port of Fix printing directives when they contain something li… by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2945
- Stable port of Diff counts are the same by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2946
- Stable port of #2940 by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2947
Full Changelog: https://github.com/graphql-java/graphql-java/compare/v19.1...v19.2
This bug fix release was made to address a specific NullPointerException
problem if consumers are explicitly setting the ExecutionInput
to null
See https://github.com/graphql-java/graphql-java/pull/2908 for the code details.
The other fixes are included because they are... well... fixes and where ready at the time.
What's Changed
- Defaults Locale when calling validation by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2908
- Handles isDeprecated not being present in the json by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2910
- Fix typo in description of skip directive by @acanda in https://github.com/graphql-java/graphql-java/pull/2915
- Xuorig Fix PR - Edge case with GraphQLTypeReference and Schema Transforms by @bbakerman in https://github.com/graphql-java/graphql-java/pull/2906
- Reduce calculation for fragments in ExecutableNormalizedOperation by @dondonz in https://github.com/graphql-java/graphql-java/pull/2911
New Contributors
- @acanda made their first contribution in https://github.com/graphql-java/graphql-java/pull/2915
Full Changelog: https://github.com/graphql-java/graphql-java/compare/v19.0...v19.1
This is a security bugfix release containing only one PR: https://github.com/graphql-java/graphql-java/pull/2902
GraphQL Java has a max token limit per request preventing DOS attacks. But in some circumstances it was not enough to prevent malicious requests. This release fixes this problem.
All details can be found here: https://github.com/graphql-java/graphql-java/pull/2892
This is a security bugfix release containing only one PR: https://github.com/graphql-java/graphql-java/pull/2897
GraphQL Java has a max token limit per request preventing DOS attacks. But in some circumstances it was not enough to prevent malicious requests. This release fixes this problem.
All details can be found here: https://github.com/graphql-java/graphql-java/pull/2892