Register reflection hints for Relay pagination types#1480
Open
seonwooj0810 wants to merge 1 commit into
Open
Conversation
graphql-java's PropertyFetchingImpl resolves Connection edges, nodes, cursors and page info via reflection. The Relay implementation classes that ConnectionFieldTypeVisitor constructs (DefaultConnection, DefaultConnectionCursor, DefaultEdge, DefaultPageInfo) are no longer present in the GraalVM reachability metadata for recent graphql-java releases, so in a native image those getter calls fail and edges are serialized with null nodes and page info. Add a RuntimeHintsRegistrar that registers INVOKE_PUBLIC_METHODS for the four Relay types so they remain reflectively accessible in a native image, and wire it through META-INF/spring/aot.factories. Closes spring-projectsgh-1479 Signed-off-by: seonwoo_jung <laborlawseon@kap.kr>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1479
Root cause
graphql-java'sPropertyFetchingImplresolves Relay connection fields (edges,node,cursor,pageInfo,hasNextPage,endCursor, …) reflectively against whatever Java object the data fetcher returns. Spring for GraphQL wrapsWindow,Slice, and other backing containers into the concretegraphql-javatypesDefaultConnection,DefaultConnectionCursor,DefaultEdge, andDefaultPageInfoinsideConnectionFieldTypeVisitor.ConnectionDataFetcher.The GraalVM reachability metadata that used to list those four classes for
graphql-javahas been dropped from recent versions of the published metadata. On the JVM the reflective lookup still works, but in a native image the getters are inaccessible andPropertyFetchingImplfalls back tonull, so relay responses come back with emptynode/pageInfoeven though the data fetcher produced the correct objects. The reporter on #1479 confirmed that adding hints for these four types restores the expected behavior.Change
Adds
RelayPaginationRuntimeHints, aRuntimeHintsRegistrarthat registersINVOKE_PUBLIC_METHODSfor the fourgraphql.relay.Default*types, and wires it throughMETA-INF/spring/aot.factories. Since Spring for GraphQL is the component that surfaces these types tographql-java, registering the hints here keeps the fix scoped to the situations where Spring actually creates them, rather than relying on upstream metadata to stay in sync.The hint only covers public getters (
INVOKE_PUBLIC_METHODS), matching whatPropertyFetchingImplactually uses; no constructor or field hints are needed because Spring instantiates these types directly.Test evidence
RelayPaginationRuntimeHintsTestscovers two things:META-INF/spring/aot.factoriesINVOKE_PUBLIC_METHODShint registered./gradlew :spring-graphql:test --tests "org.springframework.graphql.data.pagination.*"passes (existingConnectionFieldTypeVisitorTests,Base64CursorEncoderTests, plus the new tests, all green)../gradlew :spring-graphql:checkstyleMain :spring-graphql:checkstyleTestis clean.Verification done
gh pr list --repo spring-projects/spring-graphql --search "relay native hints"and a scan of the recent PR list show no open PR referencing this issue.META-INF/spring/aot.factories.main. None ofDefaultConnection/DefaultConnectionCursor/DefaultEdge/DefaultPageInfoappear inspring-graphql/src/main/resources/META-INF/native-image/.../reflect-config.json, and no existingRuntimeHintsRegistrarregisters them — verified bygrep -r "DefaultConnection\|DefaultEdge\|DefaultPageInfo" spring-graphql/src/main/.Windowrunning in native image) and a precise root-cause trace throughgraphql.schema.PropertyFetchingImpl; the reporter verified the same fix in their own application.