From 2baac78175257d05cdef5bd23d3ed977759cc3e0 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 15 Nov 2022 16:52:45 +0100 Subject: [PATCH] Only contribute hints for matching methods Closes gh-33203 --- ...lientHttpRequestFactoriesRuntimeHints.java | 53 +++++++++--------- ...HttpRequestFactoriesRuntimeHintsTests.java | 55 +++++++++++-------- 2 files changed, 58 insertions(+), 50 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesRuntimeHints.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesRuntimeHints.java index a986c20304..c47ef109a6 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesRuntimeHints.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesRuntimeHints.java @@ -17,14 +17,13 @@ package org.springframework.boot.web.client; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.net.HttpURLConnection; -import java.util.function.Consumer; import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.ReflectionHints; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.aot.hint.TypeHint; import org.springframework.aot.hint.TypeReference; import org.springframework.http.client.AbstractClientHttpRequestFactoryWrapper; import org.springframework.http.client.ClientHttpRequestFactory; @@ -52,35 +51,33 @@ class ClientHttpRequestFactoriesRuntimeHints implements RuntimeHintsRegistrar { private void registerHints(ReflectionHints hints, ClassLoader classLoader) { hints.registerField(findField(AbstractClientHttpRequestFactoryWrapper.class, "requestFactory")); - if (ClassUtils.isPresent(ClientHttpRequestFactories.APACHE_HTTP_CLIENT_CLASS, classLoader)) { - registerReflectionHints(hints, HttpComponentsClientHttpRequestFactory.class, this::onReachableHttpClient); - } - if (ClassUtils.isPresent(ClientHttpRequestFactories.OKHTTP_CLIENT_CLASS, classLoader)) { - registerReflectionHints(hints, OkHttp3ClientHttpRequestFactory.class, this::onReachableOkHttpClient); - } - registerReflectionHints(hints, SimpleClientHttpRequestFactory.class, this::onReachableHttpUrlConnection); - } - - private void onReachableHttpUrlConnection(TypeHint.Builder typeHint) { - typeHint.onReachableType(HttpURLConnection.class); - } - - private void onReachableHttpClient(TypeHint.Builder typeHint) { - typeHint.onReachableType(TypeReference.of(ClientHttpRequestFactories.APACHE_HTTP_CLIENT_CLASS)); - } - - private void onReachableOkHttpClient(TypeHint.Builder typeHint) { - typeHint.onReachableType(TypeReference.of(ClientHttpRequestFactories.OKHTTP_CLIENT_CLASS)); + hints.registerTypeIfPresent(classLoader, ClientHttpRequestFactories.APACHE_HTTP_CLIENT_CLASS, (typeHint) -> { + typeHint.onReachableType(TypeReference.of(ClientHttpRequestFactories.APACHE_HTTP_CLIENT_CLASS)); + registerReflectionHints(hints, HttpComponentsClientHttpRequestFactory.class); + }); + hints.registerTypeIfPresent(classLoader, ClientHttpRequestFactories.OKHTTP_CLIENT_CLASS, (typeHint) -> { + typeHint.onReachableType(TypeReference.of(ClientHttpRequestFactories.OKHTTP_CLIENT_CLASS)); + registerReflectionHints(hints, OkHttp3ClientHttpRequestFactory.class); + }); + hints.registerType(SimpleClientHttpRequestFactory.class, (typeHint) -> { + typeHint.onReachableType(HttpURLConnection.class); + registerReflectionHints(hints, SimpleClientHttpRequestFactory.class); + }); } private void registerReflectionHints(ReflectionHints hints, - Class requestFactoryType, Consumer hintCustomizer) { - hints.registerType(requestFactoryType, (typeHint) -> { - typeHint.withMethod("setConnectTimeout", TypeReference.listOf(int.class), ExecutableMode.INVOKE); - typeHint.withMethod("setReadTimeout", TypeReference.listOf(int.class), ExecutableMode.INVOKE); - typeHint.withMethod("setBufferRequestBody", TypeReference.listOf(boolean.class), ExecutableMode.INVOKE); - hintCustomizer.accept(typeHint); - }); + Class requestFactoryType) { + registerMethod(hints, requestFactoryType, "setConnectTimeout", int.class); + registerMethod(hints, requestFactoryType, "setReadTimeout", int.class); + registerMethod(hints, requestFactoryType, "setBufferRequestBody", boolean.class); + } + + private void registerMethod(ReflectionHints hints, Class requestFactoryType, + String methodName, Class... parameterTypes) { + Method method = ReflectionUtils.findMethod(requestFactoryType, methodName, parameterTypes); + if (method != null) { + hints.registerMethod(method, ExecutableMode.INVOKE); + } } private Field findField(Class type, String name) { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesRuntimeHintsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesRuntimeHintsTests.java index 5fe7e6c6bd..f398cf8322 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesRuntimeHintsTests.java @@ -16,6 +16,9 @@ package org.springframework.boot.web.client; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; @@ -33,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link ClientHttpRequestFactoriesRuntimeHints}. * * @author Andy Wilkinson + * @author Stephane Nicoll */ class ClientHttpRequestFactoriesRuntimeHintsTests { @@ -41,9 +45,10 @@ class ClientHttpRequestFactoriesRuntimeHintsTests { RuntimeHints hints = new RuntimeHints(); new ClientHttpRequestFactoriesRuntimeHints().registerHints(hints, getClass().getClassLoader()); ReflectionHintsPredicates reflection = RuntimeHintsPredicates.reflection(); - assertThat(reflection - .onField(ReflectionUtils.findField(AbstractClientHttpRequestFactoryWrapper.class, "requestFactory"))) - .accepts(hints); + Field requestFactoryField = ReflectionUtils.findField(AbstractClientHttpRequestFactoryWrapper.class, + "requestFactory"); + assertThat(requestFactoryField).isNotNull(); + assertThat(reflection.onField(requestFactoryField)).accepts(hints); } @Test @@ -51,13 +56,15 @@ class ClientHttpRequestFactoriesRuntimeHintsTests { RuntimeHints hints = new RuntimeHints(); new ClientHttpRequestFactoriesRuntimeHints().registerHints(hints, getClass().getClassLoader()); ReflectionHintsPredicates reflection = RuntimeHintsPredicates.reflection(); - assertThat(reflection.onMethod(ReflectionUtils.findMethod(HttpComponentsClientHttpRequestFactory.class, - "setConnectTimeout", int.class))).accepts(hints); - assertThat(reflection.onMethod( - ReflectionUtils.findMethod(HttpComponentsClientHttpRequestFactory.class, "setReadTimeout", int.class))) + assertThat(reflection + .onMethod(method(HttpComponentsClientHttpRequestFactory.class, "setConnectTimeout", int.class))) + .accepts(hints); + assertThat( + reflection.onMethod(method(HttpComponentsClientHttpRequestFactory.class, "setReadTimeout", int.class))) + .accepts(hints); + assertThat(reflection + .onMethod(method(HttpComponentsClientHttpRequestFactory.class, "setBufferRequestBody", boolean.class))) .accepts(hints); - assertThat(reflection.onMethod(ReflectionUtils.findMethod(HttpComponentsClientHttpRequestFactory.class, - "setBufferRequestBody", boolean.class))).accepts(hints); } @Test @@ -65,12 +72,11 @@ class ClientHttpRequestFactoriesRuntimeHintsTests { RuntimeHints hints = new RuntimeHints(); new ClientHttpRequestFactoriesRuntimeHints().registerHints(hints, getClass().getClassLoader()); ReflectionHintsPredicates reflection = RuntimeHintsPredicates.reflection(); - assertThat(reflection.onMethod( - ReflectionUtils.findMethod(OkHttp3ClientHttpRequestFactory.class, "setConnectTimeout", int.class))) - .accepts(hints); - assertThat(reflection.onMethod( - ReflectionUtils.findMethod(OkHttp3ClientHttpRequestFactory.class, "setReadTimeout", int.class))) - .accepts(hints); + assertThat(reflection.onMethod(method(OkHttp3ClientHttpRequestFactory.class, "setConnectTimeout", int.class))) + .accepts(hints); + assertThat(reflection.onMethod(method(OkHttp3ClientHttpRequestFactory.class, "setReadTimeout", int.class))) + .accepts(hints); + assertThat(hints.reflection().getTypeHint(OkHttp3ClientHttpRequestFactory.class).methods()).hasSize(2); } @Test @@ -78,14 +84,19 @@ class ClientHttpRequestFactoriesRuntimeHintsTests { RuntimeHints hints = new RuntimeHints(); new ClientHttpRequestFactoriesRuntimeHints().registerHints(hints, getClass().getClassLoader()); ReflectionHintsPredicates reflection = RuntimeHintsPredicates.reflection(); - assertThat(reflection.onMethod( - ReflectionUtils.findMethod(SimpleClientHttpRequestFactory.class, "setConnectTimeout", int.class))) + assertThat(reflection.onMethod(method(SimpleClientHttpRequestFactory.class, "setConnectTimeout", int.class))) + .accepts(hints); + assertThat(reflection.onMethod(method(SimpleClientHttpRequestFactory.class, "setReadTimeout", int.class))) + .accepts(hints); + assertThat(reflection + .onMethod(method(SimpleClientHttpRequestFactory.class, "setBufferRequestBody", boolean.class))) .accepts(hints); - assertThat(reflection.onMethod( - ReflectionUtils.findMethod(SimpleClientHttpRequestFactory.class, "setReadTimeout", int.class))) - .accepts(hints); - assertThat(reflection.onMethod(ReflectionUtils.findMethod(SimpleClientHttpRequestFactory.class, - "setBufferRequestBody", boolean.class))).accepts(hints); + } + + private static Method method(Class target, String name, Class... parameterTypes) { + Method method = ReflectionUtils.findMethod(target, name, parameterTypes); + assertThat(method).isNotNull(); + return method; } }