41
41
import org .apache .commons .logging .Log ;
42
42
import org .apache .commons .logging .LogFactory ;
43
43
import org .springframework .aop .Advisor ;
44
+ import org .springframework .aop .AopInvocationException ;
44
45
import org .springframework .aop .PointcutAdvisor ;
45
46
import org .springframework .aop .RawTargetAccess ;
46
47
import org .springframework .aop .TargetSource ;
72
73
* @author Juergen Hoeller
73
74
* @author Ramnivas Laddad
74
75
* @author Chris Beams
76
+ * @author Dave Syer
75
77
* @see org.springframework.cglib.proxy.Enhancer
76
78
* @see AdvisedSupport#setProxyTargetClass
77
79
* @see DefaultAopProxyFactory
@@ -330,9 +332,10 @@ private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
330
332
}
331
333
332
334
/**
333
- * Wrap a return of this if necessary to be the proxy
335
+ * Process a return value. Wraps a return of {@code this} if necessary to be the
336
+ * {@code proxy} and also verifies that {@code null} is not returned as a primitive.
334
337
*/
335
- private static Object massageReturnTypeIfNecessary (Object proxy , Object target , Method method , Object retVal ) {
338
+ private static Object processReturnType (Object proxy , Object target , Method method , Object retVal ) {
336
339
// Massage return value if necessary
337
340
if (retVal != null && retVal == target &&
338
341
!RawTargetAccess .class .isAssignableFrom (method .getDeclaringClass ())) {
@@ -341,6 +344,10 @@ private static Object massageReturnTypeIfNecessary(Object proxy, Object target,
341
344
// to itself in another returned object.
342
345
retVal = proxy ;
343
346
}
347
+ Class <?> returnType = method .getReturnType ();
348
+ if (retVal == null && returnType != Void .TYPE && returnType .isPrimitive ()) {
349
+ throw new AopInvocationException ("Null return value from advice does not match primitive return type for: " + method );
350
+ }
344
351
return retVal ;
345
352
}
346
353
@@ -381,7 +388,7 @@ public StaticUnadvisedInterceptor(Object target) {
381
388
382
389
public Object intercept (Object proxy , Method method , Object [] args , MethodProxy methodProxy ) throws Throwable {
383
390
Object retVal = methodProxy .invoke (this .target , args );
384
- return massageReturnTypeIfNecessary (proxy , this .target , method , retVal );
391
+ return processReturnType (proxy , this .target , method , retVal );
385
392
}
386
393
}
387
394
@@ -403,7 +410,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
403
410
try {
404
411
oldProxy = AopContext .setCurrentProxy (proxy );
405
412
Object retVal = methodProxy .invoke (this .target , args );
406
- return massageReturnTypeIfNecessary (proxy , this .target , method , retVal );
413
+ return processReturnType (proxy , this .target , method , retVal );
407
414
}
408
415
finally {
409
416
AopContext .setCurrentProxy (oldProxy );
@@ -429,7 +436,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
429
436
Object target = this .targetSource .getTarget ();
430
437
try {
431
438
Object retVal = methodProxy .invoke (target , args );
432
- return massageReturnTypeIfNecessary (proxy , target , method , retVal );
439
+ return processReturnType (proxy , target , method , retVal );
433
440
}
434
441
finally {
435
442
this .targetSource .releaseTarget (target );
@@ -455,7 +462,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
455
462
try {
456
463
oldProxy = AopContext .setCurrentProxy (proxy );
457
464
Object retVal = methodProxy .invoke (target , args );
458
- return massageReturnTypeIfNecessary (proxy , target , method , retVal );
465
+ return processReturnType (proxy , target , method , retVal );
459
466
}
460
467
finally {
461
468
AopContext .setCurrentProxy (oldProxy );
@@ -573,7 +580,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
573
580
this .targetClass , this .adviceChain , methodProxy );
574
581
// If we get here, we need to create a MethodInvocation.
575
582
Object retVal = invocation .proceed ();
576
- retVal = massageReturnTypeIfNecessary (proxy , this .target , method , retVal );
583
+ retVal = processReturnType (proxy , this .target , method , retVal );
577
584
return retVal ;
578
585
}
579
586
}
@@ -623,7 +630,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
623
630
// We need to create a method invocation...
624
631
retVal = new CglibMethodInvocation (proxy , target , method , args , targetClass , chain , methodProxy ).proceed ();
625
632
}
626
- retVal = massageReturnTypeIfNecessary (proxy , target , method , retVal );
633
+ retVal = processReturnType (proxy , target , method , retVal );
627
634
return retVal ;
628
635
}
629
636
finally {
0 commit comments