Bug 130119

Summary: Advice in perthis() aspect not executed for interface execution join point
Product: [Tools] AspectJ Reporter: Matthew Webster <matthew_webster>
Component: CompilerAssignee: aspectj inbox <aspectj-inbox>
Status: NEW --- QA Contact:
Severity: normal    
Priority: P3 CC: holger, vb
Version: DEVELOPMENT   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Testcase none

Description Matthew Webster CLA 2006-03-02 09:17:11 EST
The interface execution pointcut below matches whether or not the "+" (plus) is used (they are semantically equivalent):

public aspect TestAspect perthis(test(A)){
 
    // this does match at runtime with runtime test
    //pointcut test(A a): execution(public void A+.a()) && this(a);
            
    // this does not match at runtime with runtime test
    pointcut test(A a): execution(public void A.a()) && this(a);
            
    void around(A a): test(a) {
        System.err.println(thisJoinPoint);
        proceed(a);
    }
}

public  interface A {
 
            public  void a(); 
}

public class B implements A {
            
    public void a() {
        System.out.println("in B");
    }
            
    public static void main(String[] args) {
        new B().a();
    }
}

However when the same pointcut is used in a perthis() clause while the pointcut matches the associated advice is not executed.

When the code is decompiled the reason for the problem is clear. While the "bind()" call is made before the advice is invoked the class B does not implement the necessary AjcMightHaveAspect interface so the subsequent "hasAspect()" call fails.

public class B
    implements A
{

    public B()
    {
    }

    public void a()
    {
        JoinPoint joinpoint = Factory.makeJP(ajc$tjp_0, this, this);
        TestAspect.ajc$perObjectBind(this);
        if(TestAspect.hasAspect(this))
        {
            a_aroundBody1$advice(this, joinpoint, TestAspect.aspectOf(this), this, null, joinpoint);
            return;
        } else
        {
            a_aroundBody0(this, joinpoint);
            return;
        }
    }
...
}

This is a regression from AspectJ 1.2.1.
Comment 1 Matthew Webster CLA 2006-03-02 12:27:03 EST
Created attachment 35623 [details]
Testcase
Comment 2 Matthew Webster CLA 2006-03-03 06:54:38 EST
The problem seems to lie in PerObjectInterfaceTypeMunger.matches(). This uses the pointcut in the perclause. It eventually invokes ExactTypePattern.matchesStatically() which makes a distinction between pointcuts that do or do not include sub-types. This is the problem in our testcase. However the same pointcut matches when used with advice (you don't need to use "+") so something different must be happening in that case.