From eebaa3538a0c5b9ac204e5fc9f078167a6f17c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Thu, 3 Oct 2024 19:49:59 +0200 Subject: [PATCH] Fix a regression in Cglib Kotlin proxies The commit skips using UndeclaredThrowableStrategy for Kotlin classes in CglibAopProxy in order to fix a related regression caused by gh-32469. See gh-33585 --- .../aop/framework/CglibAopProxy.java | 5 +- .../aop/framework/CglibAopProxyKotlinTests.kt | 66 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 spring-aop/src/test/kotlin/org/springframework/aop/framework/CglibAopProxyKotlinTests.kt 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 856d4853871..813d0be9e09 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 @@ -206,7 +206,10 @@ class CglibAopProxy implements AopProxy, Serializable { enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setAttemptLoad(true); - enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader, undeclaredThrowableStrategy)); + enhancer.setStrategy(KotlinDetector.isKotlinType(proxySuperClass) ? + new ClassLoaderAwareGeneratorStrategy(classLoader) : + new ClassLoaderAwareGeneratorStrategy(classLoader, undeclaredThrowableStrategy) + ); Callback[] callbacks = getCallbacks(rootClass); Class[] types = new Class[callbacks.length]; diff --git a/spring-aop/src/test/kotlin/org/springframework/aop/framework/CglibAopProxyKotlinTests.kt b/spring-aop/src/test/kotlin/org/springframework/aop/framework/CglibAopProxyKotlinTests.kt new file mode 100644 index 00000000000..51dbfbbb834 --- /dev/null +++ b/spring-aop/src/test/kotlin/org/springframework/aop/framework/CglibAopProxyKotlinTests.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2002-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.aop.framework + +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.Test + +/** + * Tests for Kotlin support in [CglibAopProxy]. + * + * @author Sebastien Deleuze + */ +class CglibAopProxyKotlinTests { + + @Test + fun proxiedInvocation() { + val proxyFactory = ProxyFactory(MyKotlinBean()) + val proxy = proxyFactory.proxy as MyKotlinBean + assertThat(proxy.capitalize("foo")).isEqualTo("FOO") + } + + @Test + fun proxiedUncheckedException() { + val proxyFactory = ProxyFactory(MyKotlinBean()) + val proxy = proxyFactory.proxy as MyKotlinBean + assertThatThrownBy { proxy.uncheckedException() }.isInstanceOf(IllegalStateException::class.java) + } + + @Test + fun proxiedCheckedException() { + val proxyFactory = ProxyFactory(MyKotlinBean()) + val proxy = proxyFactory.proxy as MyKotlinBean + assertThatThrownBy { proxy.checkedException() }.isInstanceOf(CheckedException::class.java) + } + + + open class MyKotlinBean { + + open fun capitalize(value: String) = value.uppercase() + + open fun uncheckedException() { + throw IllegalStateException() + } + + open fun checkedException() { + throw CheckedException() + } + } + + class CheckedException() : Exception() +}