spring-cloud-function
spring-cloud-function copied to clipboard
Kotlin: FunctionTypeUtils do not support Kotlin functions following functional bean definition approach
Describe the bug
I am trying to follow the reference documentation section about registering functions with the Functional Bean definition approach, but using Kotlin.
Probably I am doing something wrong, but I could not find a way to define the FunctionRegistration#type
either than using org.springframework.cloud.function.context.catalog.FunctionTypeUtils#functionType()
, but seems it does not support Kotlin functions.
java.lang.IllegalArgumentException: Must be one of Supplier, Function, Consumer or FunctionRegistration. Was interface kotlin.jvm.functions.Function1
at org.springframework.util.Assert.isTrue(Assert.java:122) ~[spring-core-6.0.9.jar:6.0.9]
at org.springframework.cloud.function.context.catalog.FunctionTypeUtils.assertSupportedTypes(FunctionTypeUtils.java:536) ~[spring-cloud-function-context-4.0.3.jar:4.0.3]
at org.springframework.cloud.function.context.catalog.FunctionTypeUtils.getInputType(FunctionTypeUtils.java:327) ~[spring-cloud-function-context-4.0.3.jar:4.0.3]
at org.springframework.cloud.function.context.FunctionRegistration.type(FunctionRegistration.java:129) ~[spring-cloud-function-context-4.0.3.jar:4.0.3]
at tech.aaregall.lab.AppFunctional.initialize(AppFunctional.kt:22) ~[main/:na]
Versions:
- Spring Boot 3.1.0
- Kotlin 1.8.21
- JDK 17
- Spring Cloud 2002.0.3 (
spring-cloud-function-kotlin:4.0.3
)
Sample
package tech.aaregall.lab
import org.springframework.boot.SpringBootConfiguration
import org.springframework.cloud.function.context.FunctionRegistration
import org.springframework.cloud.function.context.FunctionalSpringApplication
import org.springframework.cloud.function.context.catalog.FunctionTypeUtils
import org.springframework.context.ApplicationContextInitializer
import org.springframework.context.support.GenericApplicationContext
@SpringBootConfiguration
class AppFunctional : ApplicationContextInitializer<GenericApplicationContext> {
fun uppercase(): (String) -> String {
return { it.uppercase() }
}
override fun initialize(context: GenericApplicationContext) {
context.registerBean("demo", FunctionRegistration::class.java,
FunctionRegistration(uppercase())
.type(FunctionTypeUtils.functionType(String::class.java, String::class.java))
)
}
}
fun main(args: Array<String>) {
FunctionalSpringApplication.run(AppFunctional::class.java, *args)
}
plugins {
id("org.springframework.boot")
id("io.spring.dependency-management")
kotlin("jvm")
kotlin("plugin.spring")
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("org.springframework.cloud:spring-cloud-function-web")
implementation("org.springframework.cloud:spring-cloud-function-kotlin")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
}
dependencyManagement {
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
}
}
The Java version works perfectly in the same project with the same approach + same dependencies.
package tech.aaregall.lab;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.cloud.function.context.FunctionRegistration;
import org.springframework.cloud.function.context.FunctionalSpringApplication;
import org.springframework.cloud.function.context.catalog.FunctionTypeUtils;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.support.GenericApplicationContext;
import java.util.function.Function;
@SpringBootConfiguration
public class AppFunctionalJavaVersion implements ApplicationContextInitializer<GenericApplicationContext> {
public static void main(String[] args) {
FunctionalSpringApplication.run(AppFunctionalJavaVersion.class, args);
}
public Function<String, String> uppercase() {
return String::toUpperCase;
}
@Override
public void initialize(GenericApplicationContext context) {
context.registerBean("demo", FunctionRegistration.class,
() -> new FunctionRegistration<>(uppercase())
.type(FunctionTypeUtils.functionType(String.class, String.class)));
}
}