Skip to content

Commit ec2a54f

Browse files
jhoellerBenjamin Reed
authored and
Benjamin Reed
committed
Consistent fallback in case of fast-class generation failure
Closes spring-projectsgh-28138 (cherry picked from commit 7aed627)
1 parent 1ec5733 commit ec2a54f

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

org.springframework.aop/src/main/java/org/springframework/aop/framework/Cglib2AopProxy.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2010 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -328,7 +328,23 @@ private Callback[] getCallbacks(Class rootClass) throws Exception {
328328
}
329329

330330
/**
331-
* Wrap a return of this if necessary to be the proxy
331+
* Invoke the given method with a CGLIB MethodProxy if possible, falling back
332+
* to a plain reflection invocation in case of a fast-class generation failure.
333+
*/
334+
private static Object invokeMethod(Object target, Method method, Object[] args, MethodProxy methodProxy)
335+
throws Throwable {
336+
try {
337+
return methodProxy.invoke(target, args);
338+
}
339+
catch (CodeGenerationException ex) {
340+
logger.warn("Unable to fast-class invoke method [" + method + "] on target [" + target + "]. Falling back to reflection.");
341+
return AopUtils.invokeJoinpointUsingReflection(target, method, args);
342+
}
343+
}
344+
345+
/**
346+
* Process a return value. Wraps a return of {@code this} if necessary to be the
347+
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
332348
*/
333349
private static Object massageReturnTypeIfNecessary(Object proxy, Object target, Method method, Object retVal) {
334350
// Massage return value if necessary
@@ -378,7 +394,7 @@ public StaticUnadvisedInterceptor(Object target) {
378394
}
379395

380396
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
381-
Object retVal = methodProxy.invoke(this.target, args);
397+
Object retVal = invokeMethod(this.target, method, args, methodProxy);
382398
return massageReturnTypeIfNecessary(proxy, this.target, method, retVal);
383399
}
384400
}
@@ -400,7 +416,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
400416
Object oldProxy = null;
401417
try {
402418
oldProxy = AopContext.setCurrentProxy(proxy);
403-
Object retVal = methodProxy.invoke(this.target, args);
419+
Object retVal = invokeMethod(this.target, method, args, methodProxy);
404420
return massageReturnTypeIfNecessary(proxy, this.target, method, retVal);
405421
}
406422
finally {
@@ -426,7 +442,7 @@ public DynamicUnadvisedInterceptor(TargetSource targetSource) {
426442
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
427443
Object target = this.targetSource.getTarget();
428444
try {
429-
Object retVal = methodProxy.invoke(target, args);
445+
Object retVal = invokeMethod(target, method, args, methodProxy);
430446
return massageReturnTypeIfNecessary(proxy, target, method, retVal);
431447
}
432448
finally {
@@ -452,7 +468,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
452468
Object target = this.targetSource.getTarget();
453469
try {
454470
oldProxy = AopContext.setCurrentProxy(proxy);
455-
Object retVal = methodProxy.invoke(target, args);
471+
Object retVal = invokeMethod(target, method, args, methodProxy);
456472
return massageReturnTypeIfNecessary(proxy, target, method, retVal);
457473
}
458474
finally {
@@ -615,7 +631,8 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
615631
// Note that the final invoker must be an InvokerInterceptor, so we know
616632
// it does nothing but a reflective operation on the target, and no hot
617633
// swapping or fancy proxying.
618-
retVal = methodProxy.invoke(target, args);
634+
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
635+
retVal = invokeMethod(target, method, argsToUse, methodProxy);
619636
}
620637
else {
621638
// We need to create a method invocation...

0 commit comments

Comments
 (0)