Skip to content

Commit d4450a8

Browse files
committed
Specific check for parent of spring-aop ClassLoader
Closes gh-30389 (cherry picked from commit 0a5aff1)
1 parent 210e47d commit d4450a8

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,33 @@ public Object getProxy(@Nullable ClassLoader classLoader) {
123123
if (logger.isTraceEnabled()) {
124124
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
125125
}
126-
if (classLoader == null || classLoader.getParent() == null) {
127-
// JDK bootstrap loader or platform loader suggested ->
128-
// use higher-level loader which can see Spring infrastructure classes
129-
classLoader = getClass().getClassLoader();
126+
return Proxy.newProxyInstance(determineClassLoader(classLoader), this.proxiedInterfaces, this);
127+
}
128+
129+
/**
130+
* Determine whether the JDK bootstrap or platform loader has been suggested ->
131+
* use higher-level loader which can see Spring infrastructure classes instead.
132+
*/
133+
private ClassLoader determineClassLoader(@Nullable ClassLoader classLoader) {
134+
if (classLoader == null) {
135+
// JDK bootstrap loader -> use spring-aop ClassLoader instead.
136+
return getClass().getClassLoader();
137+
}
138+
if (classLoader.getParent() == null) {
139+
// Potentially the JDK platform loader on JDK 9+
140+
ClassLoader aopClassLoader = getClass().getClassLoader();
141+
ClassLoader aopParent = aopClassLoader.getParent();
142+
while (aopParent != null) {
143+
if (classLoader == aopParent) {
144+
// Suggested ClassLoader is ancestor of spring-aop ClassLoader
145+
// -> use spring-aop ClassLoader itself instead.
146+
return aopClassLoader;
147+
}
148+
aopParent = aopParent.getParent();
149+
}
130150
}
131-
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
151+
// Regular case: use suggested ClassLoader as-is.
152+
return classLoader;
132153
}
133154

134155
/**

spring-aop/src/test/java/org/springframework/aop/framework/ProxyFactoryTests.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ public void testCharSequenceProxy() {
388388
CharSequence target = "test";
389389
ProxyFactory pf = new ProxyFactory(target);
390390
ClassLoader cl = target.getClass().getClassLoader();
391-
assertThat(((CharSequence) pf.getProxy(cl)).toString()).isEqualTo(target);
391+
CharSequence proxy = (CharSequence) pf.getProxy(cl);
392+
assertThat(proxy.toString()).isEqualTo(target);
392393
}
393394

394395
@Test
@@ -397,7 +398,8 @@ public void testDateProxy() {
397398
ProxyFactory pf = new ProxyFactory(target);
398399
pf.setProxyTargetClass(true);
399400
ClassLoader cl = target.getClass().getClassLoader();
400-
assertThat(((Date) pf.getProxy(cl)).getTime()).isEqualTo(target.getTime());
401+
Date proxy = (Date) pf.getProxy(cl);
402+
assertThat(proxy.getTime()).isEqualTo(target.getTime());
401403
}
402404

403405
@Test
@@ -414,7 +416,8 @@ public String getSavepointName() throws SQLException {
414416
};
415417
ProxyFactory pf = new ProxyFactory(target);
416418
ClassLoader cl = Savepoint.class.getClassLoader();
417-
assertThat(((Savepoint) pf.getProxy(cl)).getSavepointName()).isEqualTo("sp");
419+
Savepoint proxy = (Savepoint) pf.getProxy(cl);
420+
assertThat(proxy.getSavepointName()).isEqualTo("sp");
418421
}
419422

420423

0 commit comments

Comments
 (0)