From 66b88f2f1e42bc7991d2c9047fed6e5499f5cf81 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Thu, 12 May 2022 14:34:44 -0400 Subject: [PATCH] FunctionTypeUtils test for NPE Related to https://stackoverflow.com/questions/72163534/spring-batch-integration-throwns-org-springframework-messaging-messagehandlingex The `FunctionTypeUtils.isMessage()` fails with NPE when target method has non-message argument with generic parameter. Even if we instantiate the class with specific generic argument, that info is not available for reflection and `MethodParameter` end up with a generic parameter name which is essentially a `TypeVariable` The stacktrace is like this: ``` java.lang.NullPointerException: Cannot invoke "java.lang.Class.getGenericInterfaces()" because "targetType" is null at net.jodah.typetools.TypeResolver.getTypeVariableMap(TypeResolver.java:494) at net.jodah.typetools.TypeResolver.resolveRawClass(TypeResolver.java:387) at net.jodah.typetools.TypeResolver.resolveRawClass(TypeResolver.java:373) at org.springframework.cloud.function.context.catalog.FunctionTypeUtils.isMessage(FunctionTypeUtils.java:416) ``` --- .../catalog/FunctionTypeUtilsTests.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtilsTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtilsTests.java index 1f96e0ab1..874af7da0 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtilsTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtilsTests.java @@ -17,10 +17,13 @@ package org.springframework.cloud.function.context.catalog; +import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.util.Date; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -31,8 +34,10 @@ import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; import reactor.util.function.Tuple3; +import org.springframework.core.MethodParameter; import org.springframework.core.ParameterizedTypeReference; import org.springframework.messaging.Message; +import org.springframework.util.ReflectionUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -42,7 +47,7 @@ import static org.assertj.core.api.Assertions.assertThat; * */ @SuppressWarnings("unused") -public class FunctionTypeUtilsTests { +public class FunctionTypeUtilsTests { @Test public void testFunctionTypeFrom() throws Exception { @@ -147,6 +152,21 @@ public class FunctionTypeUtilsTests { assertThat(FunctionTypeUtils.isTypeCollection(new ParameterizedTypeReference>>>() { }.getType())).isFalse(); } + @Test + public void testNoNpeFromIsMessage() { + FunctionTypeUtilsTests testService = new FunctionTypeUtilsTests<>(); + + Method methodUnderTest = + ReflectionUtils.findMethod(testService.getClass(), "notAMessageMethod", AtomicReference.class); + MethodParameter methodParameter = MethodParameter.forExecutable(methodUnderTest, 0); + + assertThat(FunctionTypeUtils.isMessage(methodParameter.getGenericParameterType())).isFalse(); + } + + void notAMessageMethod(AtomicReference payload) { + + } + private static Function function() { return null; }