Community
Participate
Working Groups
I don't know if this is a bug, but cflow(cflow(...)) causes a stack overflow exception; here's the code: public class CflowCflow { public static void main(String[] args) { new C().f(); } static class C { public void f() {} } static aspect A { before(): cflow(cflow(execution(* C.f()))) {} } }
This is actually the classic case of a program containing advice that advises itself. This simpler variant also fails: public class CflowCflow { public static void main(String[] args) { new C().f(); } static class C { public void f() {} } static aspect A { before(): cflow(execution(* C.f())) {} } } In order to implement Cflow, we advise all places that *might* be in the cflow. This will include the code for the aspect too. So all the code in the aspect class file gets advised (the advice itself, the initialization logic, the static initialization logic). In calling advice we try to get hold of an instance of A() on which to call it. As the constructor of A() is advised, then when running the constructor we try and get an instance of A() on which to call it - etc,etc until we blow the stack limit. In order to get the above to work, I would put: public class CflowCflow { public static void main(String[] args) { new C().f(); } static class C { public void f() {} } static aspect A { before(): cflow(execution(* C.f())) && !within(A) {} } } And to get the double cflow case to work (yuck!): public class CflowCflow { public static void main(String[] args) { new C().f(); } static class C { public void f() {} } static aspect A { before(): cflow(cflow(execution(* C.f())) && !within(A)) && !within(A) {} } }
Fix released as part of AspectJ 1.2.1