Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] org.aspectj.weaver.tools.PointcutExpression.couldMatchJoinPointsInType(Class aClass) always returns true in all scenarios

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 <wpdutoit@xxxxxxxxx>
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
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top