Skip to content

Commit c682309

Browse files
artembilangaryrussell
authored andcommitted
GH-3558: Kotlin DSL: propagate generics info (#3561)
Fixes #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`**
1 parent e643477 commit c682309

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

spring-integration-core/src/main/java/org/springframework/integration/dsl/BaseIntegrationFlowDefinition.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,9 @@ public <P> B handle(Class<P> payloadType, GenericHandler<P> handler,
10461046
if (ClassUtils.isLambda(handler.getClass())) {
10471047
serviceActivatingHandler = new ServiceActivatingHandler(new LambdaMessageProcessor(handler, payloadType));
10481048
}
1049+
else if (payloadType != null) {
1050+
return handle(payloadType, handler::handle, endpointConfigurer);
1051+
}
10491052
else {
10501053
serviceActivatingHandler = new ServiceActivatingHandler(handler, ClassUtils.HANDLER_HANDLE_METHOD);
10511054
}

spring-integration-core/src/main/java/org/springframework/integration/handler/LambdaMessageProcessor.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,11 @@ public Object processMessage(Message<?> message) {
9494
Object[] args = buildArgs(message);
9595

9696
try {
97-
return this.method.invoke(this.target, args);
97+
Object result = this.method.invoke(this.target, args);
98+
if (result != null && org.springframework.integration.util.ClassUtils.isKotlinUnit(result.getClass())) {
99+
result = null;
100+
}
101+
return result;
98102
}
99103
catch (InvocationTargetException e) {
100104
if (e.getTargetException() instanceof ClassCastException) {

spring-integration-core/src/test/kotlin/org/springframework/integration/dsl/KotlinDslTests.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020 the original author or authors.
2+
* Copyright 2020-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -211,8 +211,8 @@ class KotlinDslTests {
211211
fun `no reply from handle`() {
212212
val payloadReference = AtomicReference<String>()
213213
val integrationFlow =
214-
integrationFlow("handlerInputChanenl") {
215-
handle<String> { payload, _ -> payloadReference.set(payload) }
214+
integrationFlow("handlerInputChannel") {
215+
handle<Message<String>> { message, _ -> payloadReference.set(message.payload) }
216216
}
217217

218218
val registration = this.integrationFlowContext.registration(integrationFlow).register()

0 commit comments

Comments
 (0)