From c682309edb3176b8993e17d4836af5811a8ab573 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Wed, 5 May 2021 15:55:42 -0400 Subject: [PATCH] GH-3558: Kotlin DSL: propagate generics info (#3561) Fixes https://github.com/spring-projects/spring-integration/issues/3558 Kotlin lambdas mostly used to configure endpoints in DSL manner are not really Java lambdas, but rather anonymous classes implementing respective Java interfaces. While in most cases such classes carry generic info for their method impls properly in Java, it is somehow doesn't work well for `GenericHandler` implemented by Kotlin lambdas * Wrap provided `GenericHandler` in the `BaseIntegrationFlowDefinition.handle()` into a Java lambda and call `handle()` recursively to carry an expected type to the `LambdaMessageProcessor` * Fix `LambdaMessageProcessor` to handle `ClassUtils.isKotlinUnit()` result of an invocation as a `null` reply **Cherry-pick to `5.4.x` & `5.3.x`** --- .../integration/dsl/BaseIntegrationFlowDefinition.java | 3 +++ .../integration/handler/LambdaMessageProcessor.java | 6 +++++- .../org/springframework/integration/dsl/KotlinDslTests.kt | 6 +++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/BaseIntegrationFlowDefinition.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/BaseIntegrationFlowDefinition.java index 8407717f8f..153f1a75b6 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/BaseIntegrationFlowDefinition.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/BaseIntegrationFlowDefinition.java @@ -1046,6 +1046,9 @@ public abstract class BaseIntegrationFlowDefinition, BeanFac Object[] args = buildArgs(message); try { - return this.method.invoke(this.target, args); + Object result = this.method.invoke(this.target, args); + if (result != null && org.springframework.integration.util.ClassUtils.isKotlinUnit(result.getClass())) { + result = null; + } + return result; } catch (InvocationTargetException e) { if (e.getTargetException() instanceof ClassCastException) { diff --git a/spring-integration-core/src/test/kotlin/org/springframework/integration/dsl/KotlinDslTests.kt b/spring-integration-core/src/test/kotlin/org/springframework/integration/dsl/KotlinDslTests.kt index fadf915e39..be3c1bd80e 100644 --- a/spring-integration-core/src/test/kotlin/org/springframework/integration/dsl/KotlinDslTests.kt +++ b/spring-integration-core/src/test/kotlin/org/springframework/integration/dsl/KotlinDslTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -211,8 +211,8 @@ class KotlinDslTests { fun `no reply from handle`() { val payloadReference = AtomicReference() val integrationFlow = - integrationFlow("handlerInputChanenl") { - handle { payload, _ -> payloadReference.set(payload) } + integrationFlow("handlerInputChannel") { + handle> { message, _ -> payloadReference.set(message.payload) } } val registration = this.integrationFlowContext.registration(integrationFlow).register()