Community
Participate
Working Groups
Build ID: I20070625-1500 Steps To Reproduce: I a using aspectj 1.5.4.200705211336 with Eclipse 3.3 (and AJDT). If I have a class in test.aspects package (C1) with a method with an @AspectJ annotation and extend that class in another package, I get several Exceptions (which are caught by Eclipse) when compiling: 1) org.aspectj.weaver.BCException at org.aspectj.weaver.bcel.BcelShadow.createMethodGen(BcelShadow.java:3479) at org.aspectj.weaver.bcel.BcelShadow.extractMethod(BcelShadow.java:3332) at org.aspectj.weaver.bcel.BcelShadow.weaveAroundClosure(BcelShadow.java:2993) at org.aspectj.weaver.bcel.BcelShadow.weaveAroundInline(BcelShadow.java:2306) at org.aspectj.weaver.bcel.BcelAdvice.implementOn(BcelAdvice.java:272) at org.aspectj.weaver.Shadow.i ... ACONST_NULL ARETURN end public Object run(Object[]) end public class test.aspects.C3$InnerClass$AjcClosure1 2) org.aspectj.weaver.BCException at org.aspectj.weaver.bcel.BcelShadow.createMethodGen(BcelShadow.java:3479) at org.aspectj.weaver.bcel.BcelShadow.extractMethod(BcelShadow.java:3332) at org.aspectj.weaver.bcel.BcelShadow.weaveAroundClosure(BcelShadow.java:2993) at org.aspectj.weaver.bcel.BcelShadow.weaveAroundInline(BcelShadow.java:2306) at org.aspectj.weaver.bcel.BcelAdvice.implementOn(BcelAdvice.java:272) at org.aspectj.weaver.Shadow.i ... nt;)V ACONST_NULL ARETURN end public Object run(Object[]) end public class test.aspects.C3$AjcClosure1 3) java.lang.IllegalStateException at org.aspectj.weaver.Shadow.getThisType(Shadow.java:94) at org.aspectj.weaver.bcel.BcelShadow.createMethodGen(BcelShadow.java:3478) at org.aspectj.weaver.bcel.BcelShadow.extractMethod(BcelShadow.java:3332) at org.aspectj.weaver.bcel.BcelShadow.weaveAroundClosure(BcelShadow.java:2993) at org.aspectj.weaver.bcel.BcelShadow.weaveAroundInline(BcelShadow.java:2306) at org.aspectj.weaver.bcel.BcelAdvice.imple ... t;)V ACONST_NULL ARETURN end public Object run(Object[]) end public class test.aspects2.C2$AjcClosure3 I will attach a test project that shows the exception More information:
Created attachment 74511 [details] Test Project The files inside of this Jar file should show the problem.
Thanks for the example code. The problem occurs because of a generated accessor. Here is a simpler failing case: -- a/A.java -- package a; public class A { protected void m() {} } -- b/B.java -- package B; public class B extends a.A { protected class Inner { public void foo() { m(); } } } -- X.aj -- public aspect X { void around(): call(* m()) {} } -- ajc -sourceroots . java.lang.IllegalStateException: at org.aspectj.weaver.Shadow.getThisType(Shadow.java:94) at org.aspectj.weaver.bcel.BcelShadow.createMethodGen(BcelShadow.java:3478) at org.aspectj.weaver.bcel.BcelShadow.extractMethod(BcelShadow.java:3332) at org.aspectj.weaver.bcel.BcelShadow.weaveAroundInline(BcelShadow.java:2351) at org.aspectj.weaver.bcel.BcelAdvice.implementOn(BcelAdvice.java:272) An accessor is generated in type B so that the call from the inner class can be made on the protected method in A. The call to m() from the inner class calls the accessor. It is the advising of the call made by the accessor method that causes the problem. The method getThisType() goes bang because the accessor is static and so where the call to method m() is made, there is no 'this'. There is a related situation for other kinds of advice, however they don't manifest as a crash like this, they simply don't match the method call joinpoint when you think they perhaps ought to. For example: before(): within(B.Inner) && call(* m()) will match if m() is public or not match if m() is protected - since in the protected case the call to m() has been converted to a call to the accessor method that is created in the outer class and the call to m() from the accessor is then *not* within(B.Inner). From inside the accessor we have no idea who really made the call - so we cannot 'recover' the fact that it was a redirect from the inner type. So... I can prevent the crash, that is easy. What to do about the wider issue is more difficult...
fix the crash for 1.5.4 - think about the other problem for 1.6.0
fix committed. avoided the crash and recognized call was from an accessor - in which case use the parameter type to the accessor as the target type (that is what the method will be called upon). test passes.
when I said test passes, I meant mine passes - looking at the attached one now!
ok - crashes fixed in the supplied application too. However, I am not going to correct the problem of the advice marker lines not being correct. The generated accessor used to call through the outer class (when aMethod is called from an inner class) does not have the right line number information attached, so the line defaults to 1. The accessor cannot have the right line number information included because it can be used from anywhere in the class. This affects just one of the cases in the supplied test program, in C2.java the call on line 18 is redirected through an accessor and so the call comes out as occurring on line 1 (all the other advice markers are OK). The important thing for now is that the compiler doesn't crash and the woven code runs. If this becomes a big problem in the future I might look at asking the compiler to produce multiple accessor methods - one for each location that needs to call out to the protected method - then each could have correct line number information.