[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[aspectj-dev] Aspect reentrancy
|
Hi,
As part of a study I am doing on cases of aspect reentrancy and how to
deal with them, I came across something that seem to be a flaw in the
language semantics of AspectJ, at least as implemented by ajc and abc.
(I assume abc developers are also reading this list)
By aspect reentrancy, I mean when an aspect matches a join point as
part of the execution of an already-matched base program join point
(eg. matching a recursive call), of its pointcuts, or of its advice.
For the first case, base-triggered reentrancy, people have learnt to
use !cflowbelow(pc()).
For the case of advice-triggered reentrancy, people can use things
like !cflow(within(A)) and !cflow(adviceexecution()...).
The strange case is pointcut-triggered reentrancy, that can occur as a
consequence of the evaluation of an if pointcut. Consider the
following example:
public aspect Tracing {
before(Point p) : execution(* Point.*(..)) && this(p)
&& if(p.getX() < 0) {
System.out.println("hola");
}
}
It turns out that this simple aspect always leads to an infinite loop.
I could not find a way to specify that the execution of getX caused by
the if pointcut be ignored.
!cflow(within(Tracing)) does not work, etc.
As far as I could find, and we have discussed that with Eric Bodden as
well in the past days, the only solution for the above Tracing aspect
to work is to move the if pointcut into an if condition in the advice.
Or are we missing something?
The crux of the problem is that both abc and ajc decide to hide all
the join points that are _lexically_ in the if pointcut, but not those
that are in the _cflow_ of the if pointcut.
This semantics seems flawed first because it hides join points that
are part of the program execution (what if I have an aspect that
controls calls to Point getters? it will never be aware that such
calls are performed by Tracing); and second because it does not make
it possible to avoid pointcut-triggered reentrancy: because the call
to getX above is hidden, I cannot discriminate the execution of getX
based on the cflow relation to getX...
In any case it seems that the semantics of an aspect should not be
changed by moving a test from an if pointcut to the advice.
I'd be happy to know what you think of this problem, in particular if
I'm missing a really good reason of why things are the way they are,
or that a Tracing aspect as defined above is a bad idea.
Regards,
-- Éric
PS: I have worked on a detailed analysis of these issues, as well as
on a concrete proposal to control aspect reentrancy at a much nicer
level of abstraction (IMHO).
An online version of the proposal is available at:
http://www.dcc.uchile.cl/~etanter/reentrancy/main.html
Reactions and comments are very welcome.