Community
Participate
Working Groups
This IS a compiler bug unlike BUG #30439. Using aspect: public aspect Foo { before () : execution(* *.main(..)) {} after () : execution(* *.main(..)) {} before( ) : execution(* *.main(..)) {} } with vanilla HelloWorld: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } gives three messages, one for each piece of advice: circular dependency at method-execution(void HelloWorld.main (java.lang.String[])) The ording of the advice is important.
This is NOT a compiler bug. Your code exactly matches the example in the semantics guide. Search for precedence from: http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj- home/doc/progguide/apbs03.html Even though I was one of the three people who came up with this design, I'm pretty sure at this point it was a language design mistake. However, I'm doubtful that it was a bad enough mistake to be worth making an incompatible change. If you want more explanation, I'm including a message I sent explaining this in August, 2002: -----Original Message----- From: Hugunin, Jim <Jim.Hugunin@parc.com> Sent: Wednesday, August 28, 2002 11:00 AM To: 'ndlesiecki@yahoo.com'; users@aspectj.org Subject: RE: Thoughts on intra-aspect precedencewhy two cases? Lesiecki Nicholas wrote: > The programming guide says that there are two cases for precedence > between > any two pieces of advice: > 1) One is after > 2) Neither is after > I知 curious as to why this system was adopted over a more > straightforward > system (advice precedence always in order of appearance). Prior to AspectJ-1.0, the rule was that advice precedence was always in order of appearance. As you point out, this seems the most straightforward approach. We had received several complaints from users that this was confusing for after advice (including at least one complaint which was published in an OOPSLA workshop paper). I remember rather vividly the design discussion around this part of the language for AspectJ-1.0. We were extremely close to deciding that our simple regular precedence rules must be right. The argument for this was classic, "While it's true that this has confused many people, the reason clearly is that they're new to the language and don't yet understand its full inner beauty and clarity. The regular rules are clearly the right thing and will be easy for any experienced AspectJ programmer to understand." Then we did a quick experiment with a simple aspect like the following up on the white-board (ignore the syntax): aspect A { pointcut callFoo(): call(void foo()); before(): callFoo () { print "first before"; } before(): callFoo () { print "second before"; } after(): callFoo () { print "first after"; } after(): callFoo () { print "second after"; } } The principle AspectJ language designers all looked at the program and described what should be printed when foo() was called. Every one said that it should be: "first before", "second before", "first after", "second after" After about a minute, we realized that we were all wrong. This put a bit of a hole in the claim that these rules were only confusing for inexperienced users of AspectJ. After looking at many other examples and trying to come up with the simplest advice precedence rules we could where after advice behaved like most everyone seemed to think it should, we settled on the rules you have above. Einstein could have easily been talking about language design when he said, "Things should be made as simple as possible -- but no simpler." The challenge in practice is figuring out where to draw that line. I don't know for certain whether or not this particular design decision will turn out to have been the best possible choice in the long run. However, I am certain that the feedback from users throughout the evolution of AspectJ has made it a far more usable language than it would have been if created in a vacuum. -Jim *** This bug has been marked as a duplicate of 30439 ***
*** Bug 40976 has been marked as a duplicate of this bug. ***