java - Aspectj - how to call advised method from within same advice, without triggering an infinite loop -
i want log method phone call create in code except ones within logger, using aspectj.
@aspect public class logger { // point cuts //----------- @pointcut("execution(* org.mydomain.*..*.*(..))") public void selectall(){} @pointcut("within(logger) && call(* *(..))") public void codewithinaspect(){} // advices //----------- @before("selectall()") public void advicethatworksfine(joinpoint joinpoint) { system.out.print(joinpoint.getsignature().tostring()); //utils.printtoconsole(joinpoint.getsignature().tostring()); } @before("selectall() && !codewithinaspect") public void advicewithinfiniteloop(joinpoint joinpoint) { //system.out.print(joinpoint.getsignature().tostring()); utils.printtoconsole(joinpoint.getsignature().tostring()); } }
the first advice in class works fine (it writes every method phone call console), sec advice causes infinite loop when calling org.mydomain.utils.utils.printtoconsole() method, advised calling advice.
i have found mutual problem described in link http://www.eclipse.org/aspectj/doc/released/faq.php#q:infiniterecursion not understand how write pointcut infinite loop not created.
plaes help
there several problems in code:
!codewithinaspect
needs parentheses: !codewithinaspect()
advicewithinfiniteloop()
combines execution()
, call()
pointcuts in way: execution(foo) && !call(bar)
. because phone call joinpoint can never execution joinpoint sec part of status true , has no effect. thus, not avoid infinite loop. you not want exclude joinpoints within aspect logger
within command flow (cflow()
) of aspect's methods, i.e. stuff straight or indirectly called them. the solution follows:
utility class log output:
class="lang-java prettyprint-override">package org.mydomain.app; public class utils { public static void printtoconsole(object object) { system.out.println(object); } }
driver application:
class="lang-java prettyprint-override">package org.mydomain.app; public class application { public static void sayhelloto(string counterpart) { utils.printtoconsole("hello " + counterpart + "!"); } public static void main(string[] args) { sayhelloto("world"); } }
logger aspect:
class="lang-java prettyprint-override">package org.mydomain.aspect; import org.aspectj.lang.joinpoint; import org.aspectj.lang.annotation.aspect; import org.aspectj.lang.annotation.before; import org.aspectj.lang.annotation.pointcut; import org.mydomain.app.utils; @aspect public class logger { @pointcut("execution(* org.mydomain..*(..))") public void selectall() {} @pointcut("cflow(within(logger))") public void codewithinaspect() {} @before("selectall() && !codewithinaspect()") public void advice(joinpoint joinpoint) { utils.printtoconsole(joinpoint); } }
console output:
class="lang-none prettyprint-override">execution(void org.mydomain.app.application.main(string[])) execution(void org.mydomain.app.application.sayhelloto(string)) execution(void org.mydomain.app.utils.printtoconsole(object)) hello world!
enjoy!
update: if want exclude advice execution command flows can utilize pointcut:
class="lang-java prettyprint-override">@pointcut("cflow(adviceexecution())") public void codewithinaspect() {}
java aspectj infinite-loop pointcut
No comments:
Post a Comment