From 947255e3774fe6248c59d2cdd6a1b06b9f6b5d9b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 18 Dec 2020 11:55:20 +0100 Subject: [PATCH] Always propagate checked exceptions from Kotlin code behind CGLIB proxies Closes gh-23844 --- .../springframework/aop/framework/CglibAopProxy.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java index 69fe9a0487..e2b822816d 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java @@ -48,6 +48,7 @@ import org.springframework.cglib.proxy.Factory; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import org.springframework.cglib.proxy.NoOp; +import org.springframework.core.KotlinDetector; import org.springframework.core.SmartClassLoader; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -752,10 +753,17 @@ class CglibAopProxy implements AopProxy, Serializable { throw ex; } catch (Exception ex) { - if (ReflectionUtils.declaresException(getMethod(), ex.getClass())) { + if (ReflectionUtils.declaresException(getMethod(), ex.getClass()) || + KotlinDetector.isKotlinType(getMethod().getDeclaringClass())) { + // Propagate original exception if declared on the target method + // (with callers expecting it). Always propagate it for Kotlin code + // since checked exceptions do not have to be explicitly declared there. throw ex; } else { + // Checked exception thrown in the interceptor but not declared on the + // target method signature -> apply an UndeclaredThrowableException, + // aligned with standard JDK dynamic proxy behavior. throw new UndeclaredThrowableException(ex); } }