29
29
import org .apache .commons .logging .LogFactory ;
30
30
import org .aspectj .weaver .BCException ;
31
31
import org .aspectj .weaver .patterns .NamePattern ;
32
- import org .aspectj .weaver .reflect .ReflectionWorld ;
33
32
import org .aspectj .weaver .reflect .ReflectionWorld .ReflectionWorldException ;
34
33
import org .aspectj .weaver .reflect .ShadowMatchImpl ;
35
34
import org .aspectj .weaver .tools .ContextBasedMatcher ;
@@ -108,6 +107,8 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
108
107
109
108
private BeanFactory beanFactory ;
110
109
110
+ private transient ClassLoader pointcutClassLoader ;
111
+
111
112
private transient PointcutExpression pointcutExpression ;
112
113
113
114
private transient Map <Method , ShadowMatch > shadowMatchCache = new ConcurrentHashMap <Method , ShadowMatch >(32 );
@@ -185,20 +186,13 @@ private void checkReadyToMatch() {
185
186
throw new IllegalStateException ("Must set property 'expression' before attempting to match" );
186
187
}
187
188
if (this .pointcutExpression == null ) {
188
- this .pointcutExpression = buildPointcutExpression ();
189
+ this .pointcutClassLoader = (this .beanFactory instanceof ConfigurableBeanFactory ?
190
+ ((ConfigurableBeanFactory ) this .beanFactory ).getBeanClassLoader () :
191
+ ClassUtils .getDefaultClassLoader ());
192
+ this .pointcutExpression = buildPointcutExpression (this .pointcutClassLoader );
189
193
}
190
194
}
191
195
192
- /**
193
- * Build the underlying AspectJ pointcut expression.
194
- */
195
- private PointcutExpression buildPointcutExpression () {
196
- ClassLoader cl = (this .beanFactory instanceof ConfigurableBeanFactory ?
197
- ((ConfigurableBeanFactory ) this .beanFactory ).getBeanClassLoader () :
198
- ClassUtils .getDefaultClassLoader ());
199
- return buildPointcutExpression (cl );
200
- }
201
-
202
196
/**
203
197
* Build the underlying AspectJ pointcut expression.
204
198
*/
@@ -252,23 +246,22 @@ public PointcutExpression getPointcutExpression() {
252
246
public boolean matches (Class <?> targetClass ) {
253
247
checkReadyToMatch ();
254
248
try {
255
- return this .pointcutExpression .couldMatchJoinPointsInType (targetClass );
256
- }
257
- catch (ReflectionWorldException rwe ) {
258
- logger .debug ("PointcutExpression matching rejected target class" , rwe );
259
249
try {
260
- // Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
261
- return getFallbackPointcutExpression (targetClass ).couldMatchJoinPointsInType (targetClass );
250
+ return this .pointcutExpression .couldMatchJoinPointsInType (targetClass );
262
251
}
263
- catch (BCException bce ) {
264
- logger .debug ("Fallback PointcutExpression matching rejected target class" , bce );
265
- return false ;
252
+ catch (ReflectionWorldException ex ) {
253
+ logger .debug ("PointcutExpression matching rejected target class - trying fallback expression" , ex );
254
+ // Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
255
+ PointcutExpression fallbackExpression = getFallbackPointcutExpression (targetClass );
256
+ if (fallbackExpression != null ) {
257
+ return fallbackExpression .couldMatchJoinPointsInType (targetClass );
258
+ }
266
259
}
267
260
}
268
261
catch (BCException ex ) {
269
262
logger .debug ("PointcutExpression matching rejected target class" , ex );
270
- return false ;
271
263
}
264
+ return false ;
272
265
}
273
266
274
267
@ Override
@@ -365,12 +358,19 @@ protected String getCurrentProxiedBeanName() {
365
358
366
359
367
360
/**
368
- * Get a new pointcut expression based on a target class's loader, rather
369
- * than the default.
361
+ * Get a new pointcut expression based on a target class's loader rather than the default.
370
362
*/
371
363
private PointcutExpression getFallbackPointcutExpression (Class <?> targetClass ) {
372
- ClassLoader classLoader = targetClass .getClassLoader ();
373
- return (classLoader != null ? buildPointcutExpression (classLoader ) : this .pointcutExpression );
364
+ try {
365
+ ClassLoader classLoader = targetClass .getClassLoader ();
366
+ if (classLoader != null && classLoader != this .pointcutClassLoader ) {
367
+ return buildPointcutExpression (classLoader );
368
+ }
369
+ }
370
+ catch (Throwable ex ) {
371
+ logger .debug ("Failed to create fallback PointcutExpression" , ex );
372
+ }
373
+ return null ;
374
374
}
375
375
376
376
private RuntimeTestWalker getRuntimeTestWalker (ShadowMatch shadowMatch ) {
@@ -396,46 +396,51 @@ private ShadowMatch getShadowMatch(Method targetMethod, Method originalMethod) {
396
396
if (shadowMatch == null ) {
397
397
synchronized (this .shadowMatchCache ) {
398
398
// Not found - now check again with full lock...
399
+ PointcutExpression fallbackExpression = null ;
399
400
Method methodToMatch = targetMethod ;
400
- PointcutExpression fallbackPointcutExpression = null ;
401
- shadowMatch = this .shadowMatchCache .get (methodToMatch );
401
+ shadowMatch = this .shadowMatchCache .get (targetMethod );
402
402
if (shadowMatch == null ) {
403
403
try {
404
- shadowMatch = this .pointcutExpression .matchesMethodExecution (targetMethod );
404
+ shadowMatch = this .pointcutExpression .matchesMethodExecution (methodToMatch );
405
405
}
406
- catch (ReflectionWorld . ReflectionWorldException ex ) {
406
+ catch (ReflectionWorldException ex ) {
407
407
// Failed to introspect target method, probably because it has been loaded
408
- // in a special ClassLoader. Let's try the original method instead...
408
+ // in a special ClassLoader. Let's try the declaring ClassLoader instead...
409
409
try {
410
- fallbackPointcutExpression = getFallbackPointcutExpression (methodToMatch .getDeclaringClass ());
411
- shadowMatch = fallbackPointcutExpression .matchesMethodExecution (methodToMatch );
412
- }
413
- catch (ReflectionWorld .ReflectionWorldException ex2 ) {
414
- if (targetMethod == originalMethod ) {
415
- shadowMatch = new ShadowMatchImpl (org .aspectj .util .FuzzyBoolean .NO , null , null , null );
410
+ fallbackExpression = getFallbackPointcutExpression (methodToMatch .getDeclaringClass ());
411
+ if (fallbackExpression != null ) {
412
+ shadowMatch = fallbackExpression .matchesMethodExecution (methodToMatch );
416
413
}
417
- else {
418
- try {
419
- shadowMatch = this .pointcutExpression .matchesMethodExecution (originalMethod );
420
- }
421
- catch (ReflectionWorld .ReflectionWorldException ex3 ) {
422
- // Could neither introspect the target class nor the proxy class ->
423
- // let's simply consider this method as non-matching.
424
- methodToMatch = originalMethod ;
425
- fallbackPointcutExpression = getFallbackPointcutExpression (methodToMatch .getDeclaringClass ());
426
- try {
427
- shadowMatch = fallbackPointcutExpression .matchesMethodExecution (methodToMatch );
428
- }
429
- catch (ReflectionWorld .ReflectionWorldException ex4 ) {
430
- shadowMatch = new ShadowMatchImpl (org .aspectj .util .FuzzyBoolean .NO , null , null , null );
431
- }
414
+ }
415
+ catch (ReflectionWorldException ex2 ) {
416
+ fallbackExpression = null ;
417
+ }
418
+ }
419
+ if (shadowMatch == null && targetMethod != originalMethod ) {
420
+ methodToMatch = originalMethod ;
421
+ try {
422
+ shadowMatch = this .pointcutExpression .matchesMethodExecution (methodToMatch );
423
+ }
424
+ catch (ReflectionWorldException ex3 ) {
425
+ // Could neither introspect the target class nor the proxy class ->
426
+ // let's try the original method's declaring class before we give up...
427
+ try {
428
+ fallbackExpression = getFallbackPointcutExpression (methodToMatch .getDeclaringClass ());
429
+ if (fallbackExpression != null ) {
430
+ shadowMatch = fallbackExpression .matchesMethodExecution (methodToMatch );
432
431
}
433
432
}
433
+ catch (ReflectionWorldException ex4 ) {
434
+ fallbackExpression = null ;
435
+ }
434
436
}
435
437
}
436
- if (shadowMatch .maybeMatches () && fallbackPointcutExpression != null ) {
438
+ if (shadowMatch == null ) {
439
+ shadowMatch = new ShadowMatchImpl (org .aspectj .util .FuzzyBoolean .NO , null , null , null );
440
+ }
441
+ else if (shadowMatch .maybeMatches () && fallbackExpression != null ) {
437
442
shadowMatch = new DefensiveShadowMatch (shadowMatch ,
438
- fallbackPointcutExpression .matchesMethodExecution (methodToMatch ));
443
+ fallbackExpression .matchesMethodExecution (methodToMatch ));
439
444
}
440
445
this .shadowMatchCache .put (targetMethod , shadowMatch );
441
446
}
0 commit comments