Fixed versions
The following example shows the “double-match problem”. Here, we only see syntactic changes. The semantic change is hidden: the advice should only execute once, not twice. When changing the pointcut for JPB to …
call(* foo(..)) && args(*,i)
… then the program should throw an exception, stating that there are different value bindings for the same joinpoint.
xpi Jps{ joinpointtype void JP(int i); joinpointtype void JPA(int i) extends JP; joinpointtype void JPB(int i) extends JP; } module Base{ contains C; from Jps exhibits { void JPA(int i): call(* foo(..)) && args(i,*); void JPB(int i): call(* foo(..)) && args(i,*); } } class C { static void foo(int a, int b) { System.out.println("foo: "+a+","+b); } public static void main(String args[]) { foo(1,2); } } module Aspects { contains DoubleAspect; } aspect DoubleAspect{ void around Jps.JP(int i) { System.out.println(System.identityHashCode(thisJoinPoint)); System.out.println(i); proceed(i * -1); } }
This is the example of looping in the case of “extends”. In our approach, there will be no looping because the aspect Asp is automatically deployed on level 1.
xpi Jps { joinpointtype void JP(); } module Base { contains Main, A, B; exhibits from Jps { void JP(): call(* print*(..)); } } class Main { public static void main(String args[]) { new A().foo(); } } class B extends A { public void foo() { //some other code here super.foo(); } } class A { public void foo() { System.out.println("foo"); } } module Aspects { contains Asp; } aspect Asp { after(): Jps.JP() { new B().foo(); } }
Similar for the case with the “use” relationship.
xpi Jps { joinpointtype void JP(); } module Base { contains A, Util; exhibits void JP() : call(* print*(..)); } class A { public static void main(String args[]) { Util.print("Hello");; } } class Util { public static void print(String s) { System.out.println(s); } } module Aspect { contains Asp; } aspect Asp { after JP() { Util.print(" World"); } }