Community
Participate
Working Groups
cannot aspect inner class constructor w/ annotated params To Reproduce: 1. Annotate the parameter of an inner class constructor. i.e., public @interface Ann { } public class Outer { public class Inner { Inner(@Ann String arg) { } } } 2. Aspect the constructor. i.e., public aspect Asp { before() : execution(new(@Ann (*), ..)){ } } 3. AJDT will report "Internal Compiler Error" with details: java.lang.IndexOutOfBoundsException at java.util.ArrayList.RangeCheck(ArrayList.java:546) at java.util.ArrayList.get(ArrayList.java:321) at org.aspectj.apache.bcel.classfile.annotation.RuntimeParameterAnnotations.getAnnotationsOnParameter(RuntimeParameterAnnotations.java:55) at org.aspectj.apache.bcel.classfile.Method.ensureParameterAnnotationsUnpacked(Method.java:294) at org.aspectj.apache.bcel.classfile.Method.getParameterAnnotations( ... ETURN constructor-execution(void Outer$Inner.<init>(Outer, java.lang.String)) end void <init>(Outer, String) end public class Outer$Inner This is for: Eclipse AspectJ Development Tools Version: 1.5.2.200804241330 AspectJ version: 1.6.0.20080423100000 Eclipse v3.3.2 M20080221-1800
should be simple fix.
The problem here is that because the inner type is non-static there is an implicit first parameter to the constructor for the Inner type which gets added by the compiler - this parameter is of type Outer (it is the enclosing instance of the outer type). The annotation data is only there for the declared parameter and so we get into trouble when iterating over both parameters and attempting to recover the annotation data (which says nothing for the other parameter).
test committed.
ok. the npe won't happen any more. But the behaviour is still not right. The extra parameter is still an issue. There is some missing internal infrastructure for getting the right modifiers for an inner class - and so the fix to do the right thing for a non-static inner class can't be put in until that infrastructure is there. This means that the behaviour right now is less than perfect: The code in comment 1 will match fine. This variant will not: @interface Ann { } class Outer { public class Inner { Inner(@Ann String arg) { } } } aspect Asp { before() : execution(new(@Ann (String), ..)){ } } Because of the rogue extra parameter that shuffles the declared parameter types along, but *not* the declared annotations! This will match (!): before() : execution(new(@Ann (*),String)) {} and this (!!): before() : execution(new(@Ann (Outer),String)) {} making high priority for fixing post 1.6.2. The required infrastructure will disturb things and I don't want to do that so close to release.
3 testcases committed
unsetting the target field which is currently set for something already released