diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandler.java index 90db9056..3cf8a24f 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandler.java @@ -35,6 +35,7 @@ import org.reactivestreams.Subscription; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import org.springframework.aot.hint.annotation.RegisterReflectionForBinding; import org.springframework.graphql.server.WebGraphQlHandler; import org.springframework.graphql.server.WebGraphQlResponse; import org.springframework.graphql.server.WebSocketGraphQlInterceptor; @@ -59,6 +60,7 @@ import org.springframework.web.reactive.socket.WebSocketSession; * @author Rossen Stoyanchev * @since 1.0.0 */ +@RegisterReflectionForBinding(GraphQlWebSocketMessage.class) public class GraphQlWebSocketHandler implements WebSocketHandler { private static final Log logger = LogFactory.getLog(GraphQlWebSocketHandler.class); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandler.java index f9686793..87913fa5 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandler.java @@ -46,6 +46,7 @@ import reactor.core.publisher.Mono; import reactor.core.scheduler.Scheduler; import reactor.core.scheduler.Schedulers; +import org.springframework.aot.hint.annotation.RegisterReflectionForBinding; import org.springframework.graphql.execution.ErrorType; import org.springframework.graphql.execution.SubscriptionPublisherException; import org.springframework.graphql.server.WebGraphQlHandler; @@ -84,6 +85,7 @@ import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler * @author Rossen Stoyanchev * @since 1.0.0 */ +@RegisterReflectionForBinding(GraphQlWebSocketMessage.class) public class GraphQlWebSocketHandler extends TextWebSocketHandler implements SubProtocolCapable { private static final Log logger = LogFactory.getLog(GraphQlWebSocketHandler.class); diff --git a/spring-graphql/src/main/resources/META-INF/native-image/org.springframework.graphql/spring-graphql/reflect-config.json b/spring-graphql/src/main/resources/META-INF/native-image/org.springframework.graphql/spring-graphql/reflect-config.json new file mode 100644 index 00000000..fab40865 --- /dev/null +++ b/spring-graphql/src/main/resources/META-INF/native-image/org.springframework.graphql/spring-graphql/reflect-config.json @@ -0,0 +1,11 @@ +[ + { + "name":"org.springframework.graphql.server.support.GraphQlWebSocketMessage", + "allDeclaredFields":true, + "allDeclaredMethods":true, + "allDeclaredConstructors":true, + "condition": { + "typeReachable": "org.springframework.graphql.client.WebSocketGraphQlTransport" + } + } +] diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandlerTests.java index 051fa27a..057e7ec3 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandlerTests.java @@ -32,6 +32,10 @@ import reactor.core.publisher.Mono; import reactor.core.publisher.Sinks; import reactor.test.StepVerifier; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.annotation.ReflectiveRuntimeHintsRegistrar; +import org.springframework.aot.hint.predicate.ReflectionHintsPredicates; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.core.ResolvableType; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferUtils; @@ -353,6 +357,23 @@ public class GraphQlWebSocketHandlerTests extends WebSocketHandlerTestSupport { .verify(TIMEOUT); } + @Test + void registerBindingReflectionOnWebSocketMessage() { + RuntimeHints runtimeHints = new RuntimeHints(); + new ReflectiveRuntimeHintsRegistrar().registerRuntimeHints(runtimeHints, GraphQlWebSocketHandler.class); + ReflectionHintsPredicates reflection = RuntimeHintsPredicates.reflection(); + assertThat(reflection.onType(GraphQlWebSocketMessage.class)).accepts(runtimeHints); + assertThat(reflection.onField(GraphQlWebSocketMessage.class, "id")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "getId")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "setId")).accepts(runtimeHints); + assertThat(reflection.onField(GraphQlWebSocketMessage.class, "type")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "getType")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "setType")).accepts(runtimeHints); + assertThat(reflection.onField(GraphQlWebSocketMessage.class, "payload")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "getPayload")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "setPayload")).accepts(runtimeHints); + } + private TestWebSocketSession handle(Flux input, WebGraphQlInterceptor... interceptors) { GraphQlWebSocketHandler handler = new GraphQlWebSocketHandler( initHandler(interceptors), diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandlerTests.java index 7cddbb04..7c3d9d05 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandlerTests.java @@ -36,6 +36,10 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.annotation.ReflectiveRuntimeHintsRegistrar; +import org.springframework.aot.hint.predicate.ReflectionHintsPredicates; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.TestThreadLocalAccessor; import org.springframework.graphql.execution.ErrorType; @@ -406,6 +410,23 @@ public class GraphQlWebSocketHandlerTests extends WebSocketHandlerTestSupport { } } + @Test + void registerBindingReflectionOnWebSocketMessage() { + RuntimeHints runtimeHints = new RuntimeHints(); + new ReflectiveRuntimeHintsRegistrar().registerRuntimeHints(runtimeHints, GraphQlWebSocketHandler.class); + ReflectionHintsPredicates reflection = RuntimeHintsPredicates.reflection(); + assertThat(reflection.onType(GraphQlWebSocketMessage.class)).accepts(runtimeHints); + assertThat(reflection.onField(GraphQlWebSocketMessage.class, "id")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "getId")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "setId")).accepts(runtimeHints); + assertThat(reflection.onField(GraphQlWebSocketMessage.class, "type")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "getType")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "setType")).accepts(runtimeHints); + assertThat(reflection.onField(GraphQlWebSocketMessage.class, "payload")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "getPayload")).accepts(runtimeHints); + assertThat(reflection.onMethod(GraphQlWebSocketMessage.class, "setPayload")).accepts(runtimeHints); + } + private void handle(GraphQlWebSocketHandler handler, TextMessage... textMessages) throws Exception { handler.afterConnectionEstablished(this.session);