If you look inside the method

PointcutExpressionImpl.couldMatchJoinPointsInType()
you will see it is only doing a 'fast match' (and the method is called
'couldMatchJoinPointsInType()', not 'doesMatchJoinPointsInType()').

Fast match is just a very quick way to say yes or no, it is not a full
analysis - and yes meaning more analysis is needed.  In the case of
execution() the fast match simply determines if you have asked to match
against something that might have execution join points.  You asked about a
class, so it said yes, it didn't look at the signature at all.

We always always suggest using within() components in pointcuts, and not
just lone kinded pointcuts (execution, call, get, set) - one reason for that
is that within has a nice fast match implementation.  If I change your
pointcut to include a within clause:

        PointcutExpression ex = p.parsePointcutExpression("within(*..Target)
&& execution(* *..Target.targetMethod1(..))");

        System.out.println(ex.couldMatchJoinPointsInType(Target.class));
        System.out.println(ex.couldMatchJoinPointsInType(Logger.class));

prints:

true
false

The fast match for within determined Logger was nothing to do with Target.


Programmatic use of the matching infrastructure is a work in progress.  Some
of the basics are there but they aren't friendly, and a number of bugzilla
requests are open to improve things.  If you want to dig about some more,
look at the CommonPointcutExpressionTests which do things like this:


    public void testMethodExecutionMatching02() {
        checkAlwaysMatches("execution(* *val*(..))", "java.lang.String",
"valueOf", "(Z)Ljava/lang/String;");
        checkAlwaysMatches("execution(String *(..))", "java.lang.String",
"valueOf", "(Z)Ljava/lang/String;");
        checkAlwaysMatches("execution(* *(boolean))", "java.lang.String",
"valueOf", "(Z)Ljava/lang/String;");
        checkAlwaysMatches("execution(* j*..*.valueOf(..))",
"java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
        checkAlwaysMatches("execution(* *(*))", "java.lang.String",
"valueOf", "(Z)Ljava/lang/String;");

        checkNeverMatches("execution(* vulueOf(..))", "java.lang.String",
"valueOf", "(Z)Ljava/lang/String;");
        checkNeverMatches("execution(int *(..))", "java.lang.String",
"valueOf", "(Z)Ljava/lang/String;");
        checkNeverMatches("execution(* valueOf(String))",
"java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
        checkNeverMatches("execution(private * valueOf(..))",
"java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
    }

    private void checkAlwaysMatches(String pointcutExpression, String type,
String methodName, String methodSignature) {
        StandardPointcutExpression ex =
pointcutParser.parsePointcutExpression(pointcutExpression);
        assertNotNull(ex);
        ResolvedType resolvedType = world.resolve(type);
        ResolvedMember method = getMethod(resolvedType, methodName,
methodSignature);
        assertNotNull("Couldn't find a method with signature " +
methodSignature, method);
        boolean b = ex.matchesMethodExecution(method).alwaysMatches();
        assertTrue("Match failed", b);
    }

    private void checkNeverMatches(String pointcutExpression, String type,
String methodName, String methodSignature) {
        StandardPointcutExpression ex =
pointcutParser.parsePointcutExpression(pointcutExpression);
        assertNotNull(ex);
        ResolvedType resolvedType = world.resolve(type);
        ResolvedMember method = getMethod(resolvedType, methodName,
methodSignature);
        assertNotNull(method);
        boolean b = ex.matchesMethodExecution(method).neverMatches();
        assertTrue(b);
    }

Andy.


2009/7/9 Wilter du Toit <[email protected]>

> Hi
>
> I was using an AspectJPointcutExpression from Spring AOP and was trying to
> have the pointcut tell me wether it could potentially match a join point in
> a specific class. I looked at the source for AspectJPointcutExpression and
> that seems exactly what it is intended to indicate when its matches(Class
> targetClass) is invoked  (from ClassFilter interface).
>
> The matches(Class targetClass) in AspectJPointcutExpression, from looking
> at the source, seems to simply delegate to
> org.aspectj.weaver.tools.PointcutExpression.couldMatchJoinPointsInType(Class
> aClass)
>
> The javadoc for
> org.aspectj.weaver.tools.PointcutExpression.couldMatchJoinPointsInType(Class
> aClass) says:
>
>
> /**
>      * Determine whether or not this pointcut could ever match a join point
> in the given class.
>      * @param aClass  the candidate class
>      * @return true iff this pointcut <i>may</i> match a join point
> within(aClass), and false otherwise
>      */
>
>
> and yet it seems to return true no matter what class is passed in! I
> created a sample scenario to demonstrate the issue with both Spring AOP and
> directly with AspectJ APIs, it is shown below. It correctly matches the
> methods, but not the class. I also tried it with the "target" pointcut
> expression and got the same behavior. Can anyone shed some light on this? Am
> I just misunderstanding the documentation for
> org.aspectj.weaver.tools.PointcutExpression.couldMatchJoinPointsInType(Class
> aClass)? Is there another way to determine whether a join point in a class
> will ever be matched by a specific
> org.aspectj.weaver.tools.PointcutExpression? Thanks
>
> With Spring AOP:
>
> -------------------
>
> AspectJExpressionPointcut aspectJPC = new AspectJExpressionPointcut();
>         aspectJPC.setExpression("execution(*
> com.company.aop.test.Target.targetMethod1(..))");
>
>         System.out.println(aspectJPC.matches(TargetImpl.class));
>         System.out.println(aspectJPC.matches(LoggerImpl.class));
>
> System.out.println(aspectJPC.getPointcutExpression().couldMatchJoinPointsInType(TargetImpl.class));
>
> System.out.println(aspectJPC.getPointcutExpression().couldMatchJoinPointsInType(LoggerImpl.class));
>
>
> System.out.println(aspectJPC.getMethodMatcher().matches(TargetImpl.class.getMethod("targetMethod1"),null));
>
>
> System.out.println(aspectJPC.getMethodMatcher().matches(TargetImpl.class.getMethod("targetMethod2"),null));
>
> System.out.println(aspectJPC.getMethodMatcher().matches(LoggerImpl.class.getMethod("logSomething"),null));
>
> Output:
>
> true
> true  # expected false here
> true
> true  # expected false here
> true
> false
> false
>
> -------------------
>
> package com.company.random;
>
> public interface Logger
> {
>     public void logSomething();
> }
>
> ------------------
>
> package com.company.aop.test;
>
> public interface Target
> {
>     public void targetMethod1();
>     public void targetMethod2();
> }
>
> ---------------
>
>
> With AspectJ:
>
>
> PointcutParser parser =
> PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
>
>         PointcutExpression expression =
> parser.parsePointcutExpression("execution(*
> com.company.aop.test.Target.targetMethod1(..))",null, new
> PointcutParameter[]{});
>
>
>
> System.out.println(expression.couldMatchJoinPointsInType(TargetImpl.class));
>
> System.out.println(expression.couldMatchJoinPointsInType(LoggerImpl.class));
>
>
> System.out.println(expression.matchesMethodExecution(TargetImpl.class.getMethod("targetMethod1")).alwaysMatches());
>
>
> System.out.println(expression.matchesMethodExecution(TargetImpl.class.getMethod("targetMethod2")).alwaysMatches());
>
> System.out.println(expression.matchesMethodExecution(LoggerImpl.class.getMethod("logSomething")).alwaysMatches());
>
> Output:
>
> true
> true # expected false here
> true
> false
> false
>
>
>
> _______________________________________________
> aspectj-users mailing list
> [email protected]
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
>
_______________________________________________
aspectj-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Reply via email to