@@ -172,7 +172,7 @@ public Object getProxy(ClassLoader classLoader) {
172
172
}
173
173
174
174
// Validate the class, writing log messages as necessary.
175
- validateClassIfNecessary (proxySuperClass );
175
+ validateClassIfNecessary (proxySuperClass , classLoader );
176
176
177
177
// Configure CGLIB Enhancer...
178
178
Enhancer enhancer = createEnhancer ();
@@ -239,31 +239,40 @@ protected Enhancer createEnhancer() {
239
239
* Checks to see whether the supplied {@code Class} has already been validated and
240
240
* validates it if not.
241
241
*/
242
- private void validateClassIfNecessary (Class <?> proxySuperClass ) {
243
- if (logger .isWarnEnabled ()) {
242
+ private void validateClassIfNecessary (Class <?> proxySuperClass , ClassLoader proxyClassLoader ) {
243
+ if (logger .isInfoEnabled ()) {
244
244
synchronized (validatedClasses ) {
245
245
if (!validatedClasses .containsKey (proxySuperClass )) {
246
- doValidateClass (proxySuperClass );
246
+ doValidateClass (proxySuperClass , proxyClassLoader );
247
247
validatedClasses .put (proxySuperClass , Boolean .TRUE );
248
248
}
249
249
}
250
250
}
251
251
}
252
252
253
253
/**
254
- * Checks for final methods on the {@code Class} and writes warnings to the log
255
- * for each one found.
254
+ * Checks for final methods on the given {@code Class}, as well as package-visible
255
+ * methods across ClassLoaders, and writes warnings to the log for each one found.
256
256
*/
257
- private void doValidateClass (Class <?> proxySuperClass ) {
258
- if (logger . isWarnEnabled ( )) {
259
- Method [] methods = proxySuperClass .getMethods ();
257
+ private void doValidateClass (Class <?> proxySuperClass , ClassLoader proxyClassLoader ) {
258
+ if (! Object . class . equals ( proxySuperClass )) {
259
+ Method [] methods = proxySuperClass .getDeclaredMethods ();
260
260
for (Method method : methods ) {
261
- if (!Object .class .equals (method .getDeclaringClass ()) && !Modifier .isStatic (method .getModifiers ()) &&
262
- Modifier .isFinal (method .getModifiers ())) {
263
- logger .warn ("Unable to proxy method [" + method + "] because it is final: " +
264
- "All calls to this method via a proxy will be routed directly to the proxy." );
261
+ int mod = method .getModifiers ();
262
+ if (!Modifier .isStatic (mod )) {
263
+ if (Modifier .isFinal (mod )) {
264
+ logger .info ("Unable to proxy method [" + method + "] because it is final: " +
265
+ "All calls to this method via a proxy will NOT be routed to the target instance." );
266
+ }
267
+ else if (!Modifier .isPublic (mod ) && !Modifier .isProtected (mod ) && !Modifier .isPrivate (mod ) &&
268
+ proxyClassLoader != null && proxySuperClass .getClassLoader () != proxyClassLoader ) {
269
+ logger .info ("Unable to proxy method [" + method + "] because it is package-visible " +
270
+ "across different ClassLoaders: All calls to this method via a proxy will " +
271
+ "NOT be routed to the target instance." );
272
+ }
265
273
}
266
274
}
275
+ doValidateClass (proxySuperClass .getSuperclass (), proxyClassLoader );
267
276
}
268
277
}
269
278
@@ -604,7 +613,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
604
613
*/
605
614
private static class DynamicAdvisedInterceptor implements MethodInterceptor , Serializable {
606
615
607
- private AdvisedSupport advised ;
616
+ private final AdvisedSupport advised ;
608
617
609
618
public DynamicAdvisedInterceptor (AdvisedSupport advised ) {
610
619
this .advised = advised ;
@@ -622,8 +631,8 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
622
631
oldProxy = AopContext .setCurrentProxy (proxy );
623
632
setProxyContext = true ;
624
633
}
625
- // May be null Get as late as possible to minimize the time we
626
- // "own" the target, in case it comes from a pool.
634
+ // May be null. Get as late as possible to minimize the time we
635
+ // "own" the target, in case it comes from a pool...
627
636
target = getTarget ();
628
637
if (target != null ) {
629
638
targetClass = target .getClass ();
@@ -689,13 +698,13 @@ private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
689
698
690
699
private final MethodProxy methodProxy ;
691
700
692
- private boolean protectedMethod ;
701
+ private final boolean publicMethod ;
693
702
694
703
public CglibMethodInvocation (Object proxy , Object target , Method method , Object [] arguments ,
695
704
Class <?> targetClass , List <Object > interceptorsAndDynamicMethodMatchers , MethodProxy methodProxy ) {
696
705
super (proxy , target , method , arguments , targetClass , interceptorsAndDynamicMethodMatchers );
697
706
this .methodProxy = methodProxy ;
698
- this .protectedMethod = Modifier .isProtected (method .getModifiers ());
707
+ this .publicMethod = Modifier .isPublic (method .getModifiers ());
699
708
}
700
709
701
710
/**
@@ -704,11 +713,11 @@ public CglibMethodInvocation(Object proxy, Object target, Method method, Object[
704
713
*/
705
714
@ Override
706
715
protected Object invokeJoinpoint () throws Throwable {
707
- if (this .protectedMethod ) {
708
- return super . invokeJoinpoint ( );
716
+ if (this .publicMethod ) {
717
+ return this . methodProxy . invoke ( this . target , this . arguments );
709
718
}
710
719
else {
711
- return this . methodProxy . invoke ( this . target , this . arguments );
720
+ return super . invokeJoinpoint ( );
712
721
}
713
722
}
714
723
}
@@ -829,8 +838,8 @@ public int accept(Method method) {
829
838
// of the target type. If so we know it never needs to have return type
830
839
// massage and can use a dispatcher.
831
840
// If the proxy is being exposed, then must use the interceptor the
832
- // correct one is already configured. If the target is not static cannot
833
- // use a Dispatcher because the target can not then be released.
841
+ // correct one is already configured. If the target is not static, then
842
+ // cannot use a dispatcher because the target cannot be released.
834
843
if (exposeProxy || !isStatic ) {
835
844
return INVOKE_TARGET ;
836
845
}
0 commit comments