[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Advice order

Hello,

I found a strange behaviour or, at least, a behaviour that I don't understand 
from the execution of two before advices. If I change the order of the before 
advices, the result is totally different. If we put the topAnnotated before 
advice in first place, the advice for nonTopAnnotated is never executed. Am I 
missing something here?

The code is as follows:

Aspect:

aspect MyAspect {

	pointcut annotated(Annotation a) : 
		call(@Annotation * *..*.*(..)) && 
		@annotation(a); 
	 
	pointcut topAnnotated(Annotation a) : 
		annotated(a) && 
		!cflowbelow(annotated(Annotation)); 
 
	pointcut notTopAnnotated(Annotation a, Annotation aTop) : 
		annotated(a) && 
		cflowbelow(topAnnotated(aTop)); 

	// If we change the order of the before advices, the non top advice is never 		
	// printed. Why?!!!
	before(Annotation a, Annotation aTop) :  
		notTopAnnotated(a, aTop) { 
		out.println("Non-top:"); 
		out.println("\tJoin point: " + thisJoinPointStaticPart); 
		out.println("\tEnclosing join point: " + thisEnclosingJoinPointStaticPart); 
		out.println("\tAnnotation: " + a); 
		out.println("\tTop annotation: " + aTop); 
	} 
	 
	before(Annotation a) :  
		topAnnotated(a) { 
		out.println("Top:"); 
		out.println("\tJoin point: " + thisJoinPointStaticPart); 
		out.println("\tEnclosing join point: " + thisEnclosingJoinPointStaticPart); 
		out.println("\tAnnotation: " + a); 
	}
}

Testing classes:

public class A { 
 
	@Annotation("A.foo") void foo() { 
		new B().foo(); 
	} 
	/*
	* Result of the main method execution
	* Top:
	* Join point: call(void teste.A.foo())
	* Enclosing join point: execution(void teste.A.main(String[]))
	* Annotation: @teste.Annotation(value=A.foo)
	* Non-top:
	* Join point: call(void teste.B.foo())
	* Enclosing join point: execution(void teste.A.foo())
	* Annotation: @teste.Annotation(value=B.foo)
	* Top annotation: @teste.Annotation(value=A.foo)
	*/
	public static void main(String[] args) { 
		new A().foo(); 
	} 
 
}

public class B { 
 
	@Annotation("B.foo")  
	void foo() { 
	} 
}

Thanks in advance,

Paulo Zenida