/* Circular aspect execution prevention Changing the parameter of method calls */ public class circles { public static int x = 0; public static boolean stop = false; public static void f(int x) { System.out.println("circles.f being executed, x=="+x); } public static void main(String[] args) { f(1); } } aspect A { pointcut acyc() : within(A) && adviceexecution(); // The following would have looped forever // before() : call(static void circles.f()) // circular before(int x) : !within(A) && call(static void circles.f(..)) && args(x) { System.out.println("advice before "+thisJoinPoint); circles.f(x+1); // this call will not reinvoke advice } void around(int x) : !cflow(acyc()) && call(static void circles.f(..)) && args(x) { System.out.println("advice around "+thisJoinPoint.getSignature()); circles.f(x+5); } // the around advice replaces the after advice - since the pointcut // for the after advice can't be in the control flow of acyc. // that is, even though circles.f is called (not within A), this // call is under the control flow of acyc /* the following choices exist for the after advice's pointcut: !within(A) : no circularity - the call is not made from within A If "call" is changed to "execution" then there is definately circularity since f can't possibly be executed within A, only called! !cflow(acyc()) has the same effect */ }