The following example exposes the problem that IIIA generates double matches in some cases: joinpointtype JP allows around { int i; } joinpointtype JPA extends JP {} joinpointtype JPB extends JP {} class C exhibits JPA, JPB { pointcut JPA: call(* foo(..)) && args(i,*); pointcut JPB: call(* foo(..)) && args(i,*); static void foo(int a, int b) { System.out.println("foo: "+a+","+b); } public static void main(String args[]) { foo(1,2); } } aspect DoubleAspect advises JP { void around(JP j) { System.out.println(System.identityHashCode(j)); System.out.println(j.i); j.i = j.i * -1; proceed(j); } } This is an example of looping in the case of "extends": joinpointtype JP allows after {} 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 exhibits JP { pointcut JP: call(* print*(..)); public void foo() { System.out.println("foo"); } } aspect Asp advises JP { after(JP jp) { new B().foo(); } } The looping case for the "use" relationship: joinpointtype JP allows after {} class A { public static void main(String args[]) { Util.print("Hello");; } } class Util exhibits JP { pointcut JP: call(* print*(..)); public static void print(String s) { System.out.println(s); } } aspect Asp advises JP { after(JP jp) { Util.print(" World"); } } As this example shows, joinpoint types cannot declare pointcuts (the code will not compile): joinpointtype A { int i; pointcut set(* *); }