-
Notifications
You must be signed in to change notification settings - Fork 603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exception caused by suspend lambda of kotlin that implements java.util.function.Consumer #1081
Comments
Have you looked at one of our tests with coroutines? - Line 34 in 71ee83e
|
Hi @olegz , Thanks a lot for your kind reply. The test code you mentioned is written in Java, while I use When comparing these codes, I got some further information. 1. when "Multi argument Kotlin functions are not currently supported" exception occurs The reason of this result is due to isTypeRepresentedByClass(functionType, Function2.class) &&
type.length == 3 &&
CoroutinesUtils.isFlowType(type[0]) &&
CoroutinesUtils.isContinuationUnitType(type[1]) Obviously, the third one which checks whether the input patameter is a 2. the problem of using @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class KotlinSuspendFunctionJUnitTest {
private lateinit var context: GenericApplicationContext
private lateinit var catalog: FunctionCatalog
@AfterEach
fun close() {
context.close()
}
@Test
fun typeDiscoveryTests() {
create(arrayOf(KotlinSuspendFlowLambdasConfiguration::class.java))
val functionCatalog = context.getBean(FunctionCatalog::class.java)
val kotlinFunction = functionCatalog.lookup<FunctionInvocationWrapper>("kotlinFunction")
Assertions.assertThat(kotlinFunction.isFunction).isTrue()
Assertions.assertThat(kotlinFunction.inputType.typeName)
.isEqualTo("reactor.core.publisher.Flux<java.lang.String>")
Assertions.assertThat(kotlinFunction.outputType.typeName)
.isEqualTo("reactor.core.publisher.Flux<java.lang.String>")
// The following code runs correctly
val result = kotlinFunction.apply(Flux.just("abcd")) as Flux<String>
StepVerifier.create(result).expectNext("ABCD").verifyComplete()
}
private fun create(types: Array<Class<*>>, vararg props: String) {
context = SpringApplicationBuilder(*types).properties(*props).run() as GenericApplicationContext
catalog = context.getBean(FunctionCatalog::class.java)
}
} As you can see, if using
val result1 = kotlinFunction.apply(flowOf("abcd"))
val result2 = result1 as Flux<String>
StepVerifier.create(result2).expectNext("ABCD").verifyComplete() An exception occurs at the
val result1 = kotlinFunction.apply(Flux.just("abcd"))
val result2 = result1 as Flow<String> An exception occurs on the type cast:
|
Describe the bug
According to the docs, a lambda can be used to implement
java.utl.function.Cusumer
.However, if calls a suspend method in the body, the lambda must add
suspend
keywords which casuses an exception ofjava.lang.UnsupportedOperationException: Multi argument Kotlin functions are not currently supported
.Sample
Suppose I have a
DataRepository
interface which extendsCoroutineCrudRepository
, hence theDataRepository#save
method is asuspend
method (In theCoroutineCrudRepository
interface, it issuspend fun <S : T> save(entity: S): T
).And the function class is
and it cause the exception
Other tries
If using
kotlinx.coroutines.flow.Flow
, a non-suspend methodCoroutineCrudRepository#saveAll
can be used. Therefore, the lambda signature can be changed to(Flow<Data>) -> Unit
which causes no exceptions in startup.However, if call the function with a message, another exception occurs:
ugly workaound
Calling
suspend
method in arunBlocking
block that makes the Consumer itself be not in a suspend one.The version of spring-cloud-function is 4.0.5 (spring-cloud 2022.0.4).
The text was updated successfully, but these errors were encountered: