Skip to content

Commit d5ff74b

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 7aaef1e commit d5ff74b

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.
@@ -212,8 +212,8 @@ class KotlinDslTests {
212212
fun `no reply from handle`() {
213213
val payloadReference = AtomicReference<String>()
214214
val integrationFlow =
215-
integrationFlow("handlerInputChanenl") {
216-
handle<String> { payload, _ -> payloadReference.set(payload) }
215+
integrationFlow("handlerInputChannel") {
216+
handle<Message<String>> { message, _ -> payloadReference.set(message.payload) }
217217
}
218218

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

0 commit comments

Comments
 (0)