-
1. Re: How to avoid intercepting recursive calls
kabirkhan Jun 8, 2007 3:54 AM (in response to system.out)You can use cflow http://labs.jboss.org/jbossaop/docs/1.5.0.GA/docs/aspect-framework/examples/cflow/cflow.html
CFlow does have some limitations though.We cannot do the full wildcard matching that we do in normal method expressions since we are limited to what is output by the stack trace.
Also, there is an overhead since we need to throw an exception for every joinpoint to evaluate the stack trace. -
2. Re: How to avoid intercepting recursive calls
system.out Jun 8, 2007 9:11 AM (in response to system.out)<cflow-stack> is not the one I am looking for. There is no stack requirement in my case. I think solution would be in <!within> keyword.
here is another example:Pointcuts: prepare() authorize() post()
User/Client calls:client ==> prepare() -> intercept it client ==> authorize() -> intercept it
but if prepare() internally is calling authorize(), then:client ==> prepare() -> intercept it prepare ==> authorize() // don't intercept it, as this call has been intercepted before within prepare method
-
3. Re: How to avoid intercepting recursive calls
kabirkhan Jun 8, 2007 10:04 AM (in response to system.out)
<cflow-stack> is not the one I am looking for.
The purpose of cflow is exactly what you mention in the original problem - you need something along the lines of:<aop> <cflow-stack name="NotRecursivePOJO"> <not-called expr="* POJO->*(..)"/> </cflow-stack> <bind pointcut="execution(public * POJO->*(..))" cflow="NotRecursivePOJO"> <interceptor class="Blah"/> </bind> </aop>
I cannot remember if wildcards are allowed in cflow-stack/not-called, if not you will need to explicitly list all methods in not-called elements:<cflow-stack name="NotRecursivePOJO"> <not-called expr="void POJO->authenticate(..)"/> <not-called expr="void POJO->prepare(..)"/> <not-called expr="void POJO->post(..)"/> </cflow-stack>
Please let me know which of these two approaches work, and I can try to update the docs
"within" is only usable with "call()" pointcuts -
4. Re: How to avoid intercepting recursive calls
system.out Jun 8, 2007 10:43 AM (in response to system.out)Thanks Kabir, I think it can be an option.
I have 2 questions now:
1. How can I exclude the first method call from <not-called> list. i.e. in my previous example, prepare() won't be intercepted if I have all 3 methods in <not-called> list? Is that correct?
2. Can <not-called> be applied at class level/package name? -
5. Re: How to avoid intercepting recursive calls
kabirkhan Jun 11, 2007 6:12 AM (in response to system.out)1) Incorrect
<aop> <cflow-stack name="NotRecursivePOJO"> <not-called expr="* POJO->prepare(..)"/> </cflow-stack> <bind pointcut="execution(public * POJO->prepare(..))" cflow="NotRecursivePOJO"> <interceptor class="Blah"/> </bind> </aop>
Will allow the method to be called. The not-called part makes sure it has not been called *previously*. Take a look at the "cflow" tutorial that comes with the dist.
2) I updated our tests and you can use wildcards so the following is valid<aop> <cflow-stack name="NotRecursivePOJO"> <not-called expr="* org.blah.POJO->*(..)"/> </cflow-stack> <bind pointcut="execution(public * org.blah.POJO->*(..))" cflow="NotRecursivePOJO"> <interceptor class="Blah"/> </bind> </aop>
You can also do more advanced things with the classname such as<aop> <cflow-stack name="NotRecursivePOJO"> <not-called expr="* @org.blah.SomeAnnotation->*(..)"/> <not-called expr="* $instanceof(org.blah.Base}->get*(..)"/> <not-called expr="* $typedef(someDef}->*(..)"/> <not-called expr="* org.blah.Value*->*(..)"/> </cflow-stack>
Note that the access specifiers, return type and parameters are not used during the matching stage since this info is not avialble in StackTraceElement, all we have are the class and the method name.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/StackTraceElement.html