Skip to content

Commit efb85d6

Browse files
committed
Apply nullable value class fix to InvocableHandlerMethod
See gh-36449
1 parent b3f01a7 commit efb85d6

5 files changed

Lines changed: 21 additions & 6 deletions

File tree

spring-core/src/test/kotlin/org/springframework/core/CoroutinesUtilsTests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ class CoroutinesUtilsTests {
230230
}
231231

232232
@Test
233-
suspend fun invokeSuspendingFunctionWithNullableValueClassParameterWithNonnullObject() {
233+
suspend fun invokeSuspendingFunctionWithNullableValueClassParameterAndNonNullParameter() {
234234
val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithNullableValueClass") }
235235
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, ValueClass("foo"), null) as Mono
236236
Assertions.assertThat(mono.awaitSingleOrNull()).isEqualTo("foo")

spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ private static class KotlinDelegate {
316316
Object arg = args[index];
317317
if (!(parameter.isOptional() && arg == null)) {
318318
KType type = parameter.getType();
319-
if (!(type.isMarkedNullable() && arg == null) &&
319+
if (!type.isMarkedNullable() &&
320320
type.getClassifier() instanceof KClass<?> kClass &&
321321
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass))) {
322322
arg = box(kClass, arg);
@@ -337,7 +337,7 @@ private static class KotlinDelegate {
337337
private static Object box(KClass<?> kClass, @Nullable Object arg) {
338338
KFunction<?> constructor = Objects.requireNonNull(KClasses.getPrimaryConstructor(kClass));
339339
KType type = constructor.getParameters().get(0).getType();
340-
if (!(type.isMarkedNullable() && arg == null) &&
340+
if (!type.isMarkedNullable() &&
341341
type.getClassifier() instanceof KClass<?> parameterClass &&
342342
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(parameterClass))) {
343343
arg = box(parameterClass, arg);

spring-web/src/test/kotlin/org/springframework/web/method/support/InvocableHandlerMethodKotlinTests.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ class InvocableHandlerMethodKotlinTests {
148148
Assertions.assertThatIllegalArgumentException().isThrownBy { invocable.invokeForRequest(request, null) }
149149
}
150150

151+
@Test
152+
fun valueClassWithNullableAndNonNullParameter() {
153+
composite.addResolver(StubArgumentResolver(LongValueClass::class.java, LongValueClass(1)))
154+
val value = getInvocable(ValueClassHandler::valueClassWithNullable.javaMethod!!).invokeForRequest(request, null)
155+
Assertions.assertThat(value).isEqualTo(1L)
156+
}
157+
151158
@Test
152159
fun valueClassWithNullable() {
153160
composite.addResolver(StubArgumentResolver(LongValueClass::class.java, null))

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ private static class KotlinDelegate {
329329
private static final String COROUTINE_CONTEXT_ATTRIBUTE = "org.springframework.web.server.CoWebFilter.context";
330330

331331
@SuppressWarnings("DataFlowIssue")
332-
public static @Nullable Object invokeFunction(Method method, Object target, Object[] args, boolean isSuspendingFunction,
332+
public static @Nullable Object invokeFunction(Method method, Object target, @Nullable Object[] args, boolean isSuspendingFunction,
333333
ServerWebExchange exchange) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
334334

335335
if (isSuspendingFunction) {
@@ -356,7 +356,7 @@ private static class KotlinDelegate {
356356
Object arg = args[index];
357357
if (!(parameter.isOptional() && arg == null)) {
358358
KType type = parameter.getType();
359-
if (!(type.isMarkedNullable() && arg == null) &&
359+
if (!type.isMarkedNullable() &&
360360
type.getClassifier() instanceof KClass<?> kClass &&
361361
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass))) {
362362
arg = box(kClass, arg);
@@ -378,7 +378,7 @@ private static class KotlinDelegate {
378378
private static Object box(KClass<?> kClass, @Nullable Object arg) {
379379
KFunction<?> constructor = Objects.requireNonNull(KClasses.getPrimaryConstructor(kClass));
380380
KType type = constructor.getParameters().get(0).getType();
381-
if (!(type.isMarkedNullable() && arg == null) &&
381+
if (!type.isMarkedNullable() &&
382382
type.getClassifier() instanceof KClass<?> parameterClass &&
383383
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(parameterClass))) {
384384
arg = box(parameterClass, arg);

spring-webflux/src/test/kotlin/org/springframework/web/reactive/result/InvocableHandlerMethodKotlinTests.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,14 @@ class InvocableHandlerMethodKotlinTests {
250250
assertExceptionThrown(result, IllegalArgumentException::class)
251251
}
252252

253+
@Test
254+
fun valueClassWithNullableAndNonNullParameter() {
255+
this.resolvers.add(stubResolver(LongValueClass(1), LongValueClass::class.java))
256+
val method = ValueClassController::valueClassWithNullable.javaMethod!!
257+
val result = invoke(ValueClassController(), method)
258+
assertHandlerResultValue(result, "1")
259+
}
260+
253261
@Test
254262
fun valueClassWithNullable() {
255263
this.resolvers.add(stubResolver(null, LongValueClass::class.java))

0 commit comments

Comments
 (0)