diff --git a/docs/src/main/asciidoc/spring-cloud-function.adoc b/docs/src/main/asciidoc/spring-cloud-function.adoc
index 530bcf335..56dee3722 100644
--- a/docs/src/main/asciidoc/spring-cloud-function.adoc
+++ b/docs/src/main/asciidoc/spring-cloud-function.adoc
@@ -467,7 +467,7 @@ The above represents Kotlin lambdas configured as Spring beans. The signature of
While mechanics of Kotlin-to-Java mapping are outside of the scope of this documentation, it is important to understand that the
same rules for signature transformation outlined in "Java 8 function support" section are applied here as well.
-To enable Kotlin support all you need is to add `spring-cloud-function-kotlin` module to your classpath which contains the appropriate
+To enable Kotlin support all you need is to add Kotlin SDK libraries on the classpath which will trigger appropriate
autoconfiguration and supporting classes.
=== Function Component Scan
diff --git a/pom.xml b/pom.xml
index 4070b5243..9bfa41131 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,8 +51,8 @@
spring-cloud-function-samples
spring-cloud-function-deployer
spring-cloud-function-adapters
- spring-cloud-function-kotlin
spring-cloud-function-rsocket
+ spring-cloud-function-kotlin
docs
diff --git a/spring-cloud-function-kotlin/README.adoc b/spring-cloud-function-kotlin/README.adoc
new file mode 100644
index 000000000..e76a1c926
--- /dev/null
+++ b/spring-cloud-function-kotlin/README.adoc
@@ -0,0 +1,4 @@
+!!! INTERNAL !!!
+
+Contains only Kotlin tests.
+Since version 3.1.3, user's should not be declaring explicit dependency on this module.
\ No newline at end of file
diff --git a/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinTests.java b/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinTests.java
index 6198842d0..dd715c8ff 100644
--- a/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinTests.java
+++ b/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinTests.java
@@ -33,6 +33,7 @@ import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.messaging.support.MessageBuilder;
import static org.assertj.core.api.Assertions.assertThat;
@@ -83,6 +84,30 @@ public class ContextFunctionCatalogAutoConfigurationKotlinTests {
assertThat(functionType.getActualTypeArguments().length).isEqualTo(2);
assertThat(functionType.getActualTypeArguments()[0].getTypeName()).isEqualTo(Person.class.getName());
assertThat(functionType.getActualTypeArguments()[1].getTypeName()).isEqualTo(String.class.getName());
+
+
+ function = this.context.getBean("kotlinListPojoFunction");
+ functionType = (ParameterizedType) FunctionTypeUtils.discoverFunctionType(function, "kotlinListPojoFunction", this.context);
+ assertThat(functionType.getRawType().getTypeName()).isEqualTo(Function.class.getName());
+ assertThat(functionType.getActualTypeArguments().length).isEqualTo(2);
+ assertThat(functionType.getActualTypeArguments()[0].getTypeName()).isEqualTo("java.util.List");
+ assertThat(functionType.getActualTypeArguments()[1].getTypeName()).isEqualTo(String.class.getName());
+ }
+
+ @Test
+ public void testWithComplexTypesAndRouting() {
+ create(new Class[] { KotlinLambdasConfiguration.class,
+ SimpleConfiguration.class });
+
+ FunctionInvocationWrapper function = this.catalog.lookup("kotlinListPojoFunction");
+ String result = (String) function.apply("[{\"name\":\"Ricky\"}]");
+ assertThat(result).isEqualTo("List of: Ricky");
+
+ function = this.catalog.lookup(Function.class, "functionRouter");
+ result = (String) function.apply(MessageBuilder.withPayload("[{\"name\":\"Ricky\"}]")
+ .setHeader("spring.cloud.function.definition", "kotlinListPojoFunction").build());
+ assertThat(result).isEqualTo("List of: Ricky");
+
}
@Test
diff --git a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinLambdasConfiguration.kt b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinLambdasConfiguration.kt
index 00af0ca41..9e85d664b 100644
--- a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinLambdasConfiguration.kt
+++ b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinLambdasConfiguration.kt
@@ -20,6 +20,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.util.function.Function
+import java.util.List
/**
* @author Oleg Zhurakousky
@@ -37,6 +38,13 @@ class KotlinLambdasConfiguration {
fun kotlinPojoFunction(): (Person) -> String {
return { it.name.toString()}
}
+
+ @Bean
+ fun kotlinListPojoFunction(): (List) -> String {
+ return {
+ "List of: " + it.get(0).name
+ }
+ }
@Bean
fun kotlinConsumer(): (String) -> Unit {