Skip to content

@Async event listener suspending function throws IllegalArgumentException #36214

@joaodias14

Description

@joaodias14

Spring Framework 7.0.3
Java 17
Kotlin 2.2.21 (Coroutines 1.10.2)

While asynchronously handling an event, a suspending function throws IllegalArgumentException as follows:

java.lang.IllegalArgumentException: Invalid return type for async method (only Future and void supported): class java.lang.Object
	at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.doSubmit(AsyncExecutionAspectSupport.java:290) ~[spring-aop-7.0.3.jar:7.0.3]
	at org.springframework.aop.interceptor.AsyncExecutionInterceptor.invoke(AsyncExecutionInterceptor.java:127) ~[spring-aop-7.0.3.jar:7.0.3]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-7.0.3.jar:7.0.3]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:719) ~[spring-aop-7.0.3.jar:7.0.3]
	at com.example.demo.EventHandler$$SpringCGLIB$$0.handleCustomEventFail(<generated>) ~[classes/:na]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:565) ~[na:na]

The event listener function:

    @Async
    @EventListener
    suspend fun handleCustomEventFail(customSpringEvent: CustomSpringEvent) {
        println("[suspend] Handling ${customSpringEvent.id} event")
    }

A similar event listener non-suspending function works just fine:

    @Async
    @EventListener
    fun handleCustomEventSuccess(customSpringEvent: CustomSpringEvent) {
        println("[non-suspend] Handling ${customSpringEvent.id} event")
    }

A minimal reproducible example is available at https://github.com/joaodias14/demo-async.

We can workaround it by using a coroutine builder function, such as CoroutineScope.launch(), to explicitly start a coroutine, but it would be great if @Async works seamlessly with suspending functions.

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions