Java annotations - javac compiler bug?
Asked Answered
V

1

11

I came across a strange effect in connection with annotations on method parameters in a nested class. Looks very much like a compiler issue to me. See below for details and steps to reproduce.

Compile the following class with javac (I used javac 1.7.0_51). Note the annotated parameter "boolean param3".

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);
        }
    }
}

Then examine the nested class with javap (i.e. javap -p -v -c TestAnnotations$TestInner.class). Its constructor looks as follows.

 public test.TestAnnotations$TestInner(test.TestAnnotations, java.lang.String, 
                                                java.lang.Object, boolean);
   flags: ACC_PUBLIC
   Code:
     stack=2, locals=5, args_size=5
        0: aload_0
        1: aload_1
        2: putfield      #1                  // Field this$0:Ltest/TestAnnotations;
        5: aload_0
        6: invokespecial #2                  // Method java/lang/Object."<init>":()V
        9: return
     LineNumberTable:
       line 16: 0
   RuntimeInvisibleParameterAnnotations:
     0:
     1:
     2:
       0: #18()

Note the number of annotations in the attribute RuntimeInvisibleParameterAnnotations - it's 3. At the same time we now observe 4 method parameters because of one additional test.TestAnnotations at the beginning (it is used to pass a reference to TestAnnotations.this into the inner class). This means, @MyAnnotation is now refering to Object param2, shifted by 1 to the left.

According to the Virtual Machine Specification the number of annotations should be the same as the number of method parameters:

num_parameters

The value of the num_parameters item gives the number of parameters of the method represented by the method_info structure on which the annotation occurs. (This duplicates information that could be extracted from the method descriptor (§4.3.3).)

Here we clearly see a violation. Does anyone know the reason? Is it really what it seems to be, just a compiler bug?

Volans answered 27/2, 2014 at 10:20 Comment(0)
H
8

This is a javac compiler bug, see: https://bugs.openjdk.java.net/browse/JDK-8065132 that I just filed.

Hartsock answered 17/11, 2014 at 16:41 Comment(1)
Good to know. This issue was found with the decompiler Fernflower which is now part of IntelliJ IDEA. We had to implement a workaround for mapping annotations to parameters, starting now at the back of the list.Volans

© 2022 - 2024 — McMap. All rights reserved.