FULL PRODUCT VERSION :
C:\>java -version
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
C:\>ver
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
See the source code attached below. After compiling this class the constructor of TestInner has 3 annotation items in the RuntimeInvisibleParameterAnnotations attribute (can be checked with javap). However it has now 4 method parameters because of one additional TestAnnotations at the front (in order to pass a reference to TestAnnotations.this into the inner class).
This means, the correlation between parameters and annotations is broken after compilation. Annotations are shifted by 1 to the left. It's a violation of the Virtual Machine Specification which defines the number of annotations to be the same as the number of parameters.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Compile the source class (see attached code) with javac. Note the annotated parameter "boolean param3".
2) Examine the nested class with javap (i.e. javap -p -v -c TestAnnotations$TestInner.class).
3) You'll see something like following information:
RuntimeInvisibleParameterAnnotations:
0:
1:
2:
0: #18()
Note the number of annotations in the attribute RuntimeInvisibleParameterAnnotations - it's 3.
4) At the same time we now observe 4 method parameters:
public TestAnnotations$TestInner(TestAnnotations, java.lang.String,
java.lang.Object, boolean);
This means, @MyAnnotation is now refering to Object param2, shifted by 1 to the left => error.
5) Number of annotation items in the RuntimeInvisibleParameterAnnotations attiribute should be the same as the number of method parameters => error.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Number of annotation items in the RuntimeInvisibleParameterAnnotations attiribute should be the same as the number of method parameters.
ACTUAL -
Number of annotation items in the RuntimeInvisibleParameterAnnotations attiribute is less than the number of method parameters.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public class TestAnnotations {
public String a;
@Retention(RetentionPolicy.CLASS)
@interface MyAnnotation {}
protected class TestInner {
public TestInner(String param1, Object param2,
@MyAnnotation boolean param3) {}
public void accessField() {
System.out.println(TestAnnotations.this.a);
}
}
}
---------- END SOURCE ----------