Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] cflowbelow does not work in constructor?

Construction join points are a subtle thing to understand.... because object construction in Java is actually quite complicated! In this case what's happening is that there can be no statements before a super or other constructor call inside a constructor body. The "execution" join point for a constructor begins *after* the call to super/this (http://www.eclipse.org/aspectj/doc/released/progguide/semantics-joinPoints.html).  In the case of your sample program therefore, the flow actually is:

call this(1)

begin join point for execution C(int n)
start cflow
this.n = n;
end cflow
end join point for execution C(int n)

begin join point for C()  [note we're not in the cflow of C(int n) anymore]
end join point for C()

If you use initialization instead of execution, you'll only get one invocation of the advice: 

    pointcut construction(C c):
        initialization(C.new(..)) &&
        this(c);

    after(C c) returning:
        construction(c) {
        System.out.println("a C instance constructed");
    }

(note there's no need for cflowbelow at all with this solution).

Regards, Adrian.       

On 2 Sep 2006, at 09:29, Rice Yeh wrote:

I have an aspect A and a java class C like the following. I want to do something (in my example, it is printing out a message) ONCE after an instnace of C is constructed. Because I just want this thing be done ONCE, I use !cflowbelow to prevent things done when a constuctor invocation is called by top level constructor. However, it does not work. The printing message is printed twice.  Does cflowbelow not work in constructor? Or what I do is wrong?

aspect A {
   
    // TODO why does cflowbelow not behavior correctly on constructor like on method?
    pointcut construction(C c):
        execution(C.new(..)) &&
        this(c);
   
    after(C c) returning:
            construction(c) &&
            !cflowbelow(construction(C)) {
        System.out.println("a C instance constructed");
    }   
}

class C {
  private int n;

  public C() {
     this(1);
  }

  public C(int n) {
     this.n = n;
  }

    public static void main(String[] args) {
        C c = new C();
    }
}

Regards,
Rice
_______________________________________________
aspectj-users mailing list



Back to the top