Referencing parameter names in SpEL expressions fails when using Kotlin suspending functions.

For example

@Cacheable(cacheNames = ["cache"], condition = "#key.startsWith('hello')")
open suspend fun getConditionalCache(key: String): Any {
    // …

Fails with:

EL1004E: Method call: Method startsWith(java.lang.String) cannot be found on type java.lang.Object[]
org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method startsWith(java.lang.String) cannot be found on type java.lang.Object[]
    at org.springframework.expression.spel.ast.MethodReference.findAccessorForMethod(MethodReference.java:226)
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:135)
    at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:55)
    at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:387)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:92)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:117)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:308)
    at org.springframework.cache.interceptor.CacheOperationExpressionEvaluator.condition(CacheOperationExpressionEvaluator.java:108)
    at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.isConditionPassing(CacheAspectSupport.java:763)
    at org.springframework.cache.interceptor.CacheAspectSupport.isConditionPassing(CacheAspectSupport.java:583)
    at org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:534)
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:402)
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:345)
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:64)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)

The type java.lang.Object[] comes from the suspending function, getConditionalCache, having an additional Continuation parameter that is implicitly passed to it when it is invoked.

Comment From: sdeleuze

This was broken at some point but seems to work now with Kotlin 1.7+, so I have just added related tests. An additional Object parameter is added by Kotlin instead transforming the last one to an array, not sure when that changed. Please provide a repro if you see it still broken.

Comment From: zzhujing

it error also now , i use spring 6.0.8 and kotlin 1.8.22

Comment From: sdeleuze

@zzhujing Please provide a reproducer as an attached archive or a link to a repository in a new issue if you want us to have a look.