Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Guidaance on Cflow usage

Hi Donal -

I agree with Ram and Gregor but wanted to add...

You discovered some important things about cflow
and unlearned two common initial misconceptions
(so common they're worth beating to death!):

- aspects-over-here are just inserting   | not 
  code into code-over there              | true
  
- statements are join points             | not true

Aspects can affect everything, including other 
aspects and themselves.  And some program statements
are the "static shadow" of a join point - i.e., the
place where a compiler/weaver can implement advice -
but they are NOT join points.

These are a key points to remember about AspectJ, 
not least because the contrary misconceptions are 
common and misleading.

When expectations don't match what's happening, consider
checking the programming guide semantics appendix 
to see if expectations are off.  Here it says

  The cflow pointcut picks out all join points that 
  occur between entry and exit of each join point P 
  picked out by Pointcut, including P itself.

So any join point, from advice or not, that runs in the 
same thread after the entry to join point P and before 
the exit, is considered to be in the control flow of P.
The guide does not take pains at that point to correct
the misreading that the join points at issue are only
in the "non-aspect" code, because AspectJ does not make 
that distinction.  That's why the misconception is
pernicious: you can have it and not have it bite you
until later, after it's infected your thinking.

Similarly, call(..) and execution(..) (which take method
or constructor signatures), will pick out their join points
no matter "where" their static shadow is in the code the
compiler controls.  ("call(* Cflow.*(..))" would pick 
out any call to a _method_ declared in Cflow.) 
Unless, e.g., you exclude certain scopes, e.g.,
!within(Cflow).

!within(Cflow) will only exclude join points staticly 
sited in Cflow.  If the advice called a method
in another class which ran code that was advised by the 
same advice, you would again get infinite recursion, even
using !within(Cflow).  But you can say   

   !cflow(adviceexecution() && within(Cflow))

"not in the control flow of advice in the Cflow aspect"

However, using !within(Type) is better if it works 
because it's resolved at compile/weave time.  Dynamic
pointcuts like cflow and args cam require a runtime 
check.  But the important thing is to understand how
the idiom !within(Cflow) works because it only prevents
one kind of infinite recursion.

Sorry if this sounded pedantic, but unlearning these
is an important step in picking up AspectJ, so it's
important to recognize that the conclusions you came 
to as you worked through the cflow behavior you saw
were correct and important.  

Wes

Doc links on point:
http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/doc/progguide/semantics-pointcuts.html#d0e5019
http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/doc/faq.html#q:recursiveentrypoints
http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/doc/faq.html#q:infiniterecursion

On Sun, 17 Aug 2003 14:26:23 -0700 (PDT)
 Ramnivas Laddad <ramnivas@xxxxxxxxx> wrote:
> Donal,
> 
> You are right; changing cflow() to cflowbelow() does not
> help.
> You need to use the "&& !within(<Aspect>)" idiom to
> prevent 
> the infinite recursion. Modify your AddCflow() pointcut
> as 
> follows:
> 
> pointcut AddCflow():  cflow( execution( *
> WordCounter.Add( * )))
>     && !within(Cflow);
> 
> This way the control-flow introduced by advice itself is
> not advised,
> thus preventing the infinite recursion.
> 
> -Ramnivas
> 
> --- Donal Lafferty <laffertd@xxxxxxxxx> wrote:
> > 1. Using cflowbelow does not help.  In the example
> provided, the
> > pointcut argument of the cflow designator does not
> explicitly match
> > the
> > advice in Cflow.aj.  So, using cflowbelow should result
> in the same
> > behaviour, and I get the same behaviour when I modify
> the pointcut to
> > use cflow instead of cflowbelow.
> > 
> > 2. Perhaps the behaviour I'm seeing is not a problem.
>  Maybe cflow
> > should match all join points during the execution, even
> if they are
> > introduced by virtue of the same cflow call.  In this
> light its okay
> > that calls advice in Cflow.aj are caught.
> > 
> > 3.  If it is okay for advice statements of an aspect to
> match
> > pointcuts
> > in the same aspect, then I shouldn't have to use the
> mangled name to
> > do
> > it.  Should I?  If advice statements are legitimate
> join points, then
> > I
> > would expect to be able to use execution designators to
> pick them
> > out.
> > In a way I can, ex. call( * *.*( * )) seems to select
> calls to the
> > advice in cflow.aj.  However, given the claim that
> aspects are
> > modelled
> > on Java types, I would expect that something like call(
> * Cflow.*( *
> > ))
> > would also select advice from the aspect Cflow.
>  Unfortunately it
> > does
> > not.
> > 
> > 
> > DL
> > 
> > 
> > -----Original Message-----
> > From: aspectj-users-admin@xxxxxxxxxxx
> > [mailto:aspectj-users-admin@xxxxxxxxxxx] On Behalf Of
> Ramnivas Laddad
> > Sent: 16 August 2003 20:08
> > To: aspectj-users@xxxxxxxxxxx
> > Subject: Re: [aspectj-users] Guidaance on Cflow usage
> > 
> > Donal,
> > 
> > You need to use cflowbelow() pointcut to exclude the
> join point
> > itself. 
> > 
> > There is a sample chapter (chapter 3) from my book
> posted that 
> > covers control-flow based pointcuts:
> > http://www.manning.com/laddad/
> > 
> > -Ramnivas
> > 
> > --- Donal Lafferty <laffertd@xxxxxxxxx> wrote:
> > > Hi!
> > > 
> > > I'm having trouble coming to grasps with cflow
> pointcuts.  In the
> > > example below, I was surprised to find out that cflow
> advice is
> > > included
> > > in the set of cflow join points, which leads to an
> infinite
> > > recursion.
> > > Although I'm tempted to submit this as a bug, I'm not
> wholly
> > > convinced I
> > > understand what I'm doing.  Moreover, the bug
> submission system is
> > > down.
> > > 
> > > Any comments on the problem are more than welcome!
> > > 
> > > Cheers,
> > > 
> > > 
> > > DL
> > > 
> > > 
> > > WordCounterDemo.java
> > > 
> > > class WordCounterDemo 
> > > {
> > >   static String[] smallSample= {"This", "demos",
> "infinite",
> > "loop",
> > > "in", 
> > >                                  "cflow", "before",
> "advice"};
> > > 
> > >   public static void main(String[] args) {
> > >     WordCounter wordCounter = new WordCounter();
> > >     String word;
> > >     String[] wordList1 = smallSample;
> > >     int words = 0;
> > >     for (int i = 0; i < wordList1.length; i++) {
> > >       word = smallSample[i];
> > >       System.out.println("Adding " + word +", as word
> #" + 
> > > (++words));
> > >       wordCounter.Add(word);
> > >     }
> > >   }
> > > }
> > > 
> > > WordCounter.java
> > > 
> > > public class WordCounter {
> > >   public void Add(String word) {
> > >     System.out.println("Add entry, word =
> "+word.toString());
> > >   }
> > > }
> > > 
> > > Cflow.aj
> > > 
> > > public aspect Cflow {
> > >   pointcut AddCflow():  cflow( execution( *
> WordCounter.Add( * )));
> > > 
> > >   // In AspectJ 1.0.6 and 1.1 here is an infinite
> loop here,
> > because
> > > the
> > > 
> > >   // before advice is itself considered a join point
> in the cflow.
> > >   before(): AddCflow() { System.out.println("Before
> advice call" );
> > }
> > > }
> > > 
> > > CflowWeave.lst
> > > 
> > > WordCounterDemo.java
> > > WordCounter.java
> > > Cflow.aj
> > > 
> > > 
> > > Which compiles with:
> > > 
> > > ajc -argfile CflowWeave.lst
> > > 
> > > And runs with:
> > > 
> > > java -classpatch "%CLASSPATH;./" WordCounterDemo
> > > 
> > > Gives the output
> > > 
> > > Adding This, as word#1
> > > Exception in thread "main"
> java.langStackOverflowError
> > > 
> > > 
> > > 
> > > _______________________________________________
> > > aspectj-users mailing list
> > > aspectj-users@xxxxxxxxxxx
> > > http://dev.eclipse.org/mailman/listinfo/aspectj-users
> > 
> > 
> > __________________________________
> > Do you Yahoo!?
> > Yahoo! SiteBuilder - Free, easy-to-use web site design
> software
> > http://sitebuilder.yahoo.com
> > _______________________________________________
> > aspectj-users mailing list
> > aspectj-users@xxxxxxxxxxx
> > http://dev.eclipse.org/mailman/listinfo/aspectj-users
> > 
> > _______________________________________________
> > aspectj-users mailing list
> > aspectj-users@xxxxxxxxxxx
> > http://dev.eclipse.org/mailman/listinfo/aspectj-users
> 
> 
> __________________________________
> Do you Yahoo!?
> Yahoo! SiteBuilder - Free, easy-to-use web site design
> software
> http://sitebuilder.yahoo.com
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top