jdeps and annotations parameters

Alex Buckley alex.buckley at oracle.com
Wed Sep 9 01:12:52 UTC 2015


Jeff,

I confirm (JDK 8u40) that in an instance/static initializer, where a 
local variable declaration includes an annotated type, there is no 
RuntimeVisibleTypeAnnotations attribute emitted for the type annotation! 
This is so even when the correct meta-annotations appear on the 
declaration of the annotation type:

   @Target(ElementType.TYPE_USE)
   @Retention(RetentionPolicy.RUNTIME)

In a ctor, the same local variable declaration does cause a 
RuntimeVisibleTypeAnnotations attribute to be emitted for the type 
annotation.

I assume the difference stems from the fact that an annotation on a 
local variable declaration (the declaration, not its type) was 
traditionally never emitted into the class file, regardless of @Target. 
In SE 8, an annotation on the type of a local variable declaration can 
be emitted into the class file, but presumably some old code in javac is 
special-casing initializers and wasn't updated to understand type 
annotations therein.

Jon,

Can you confirm my presumption?

Alex

On 9/8/2015 3:28 PM, Jeff Hain wrote:
>
> Hi Alex.
>
>
>
>  >Either this is a huge bug in javac or you're not looking in the right
>  >place. The code in an instance initializer compiles into the same <init>
>  >method as the code in a constructor, so I would expect the <init> method
>  >to have a RuntimeVisibleTypeAnnotations attribute whether the local
>  >variable (whose type is annotated) exists in {...} or a ctor.
>
>
>
> Here are the classes I parsed to test that (using the same annotation as
> I described),
> and bellow their respective constant pool, which are quite different,
> with the
> non-constructor one NOT containing RuntimeVisibleTypeAnnotations
> (compiled with JDK8_60, -source 1.8 -target 1.8 (I guess the defaults
> anyway)):
>
>
>
> /**
>   * <init> method.
>   */
> public static class MyMethodCodeInitBlock {
>      {
>          // String will not make it into the class file.
>
> @A_TYPE_USE_R_COMPLEX(nbrClsArr={Long.class},tooStrong="",rounding=RoundingMode.UNNECESSARY,doc=@Documented)
>          Integer foo = 1;
>          try {
>              MyBlackHole.blackHole(foo);
>          } catch (RuntimeException e) {
>              throw e;
>          }
>      }
> }
>
> /**
>   * <init> method.
>   */
> public static class MyMethodCodeConstructor {
>      public MyMethodCodeConstructor() {
>          // String will not make it into the class file.
>
> @A_TYPE_USE_R_COMPLEX(nbrClsArr={Long.class},tooStrong="",rounding=RoundingMode.UNNECESSARY,doc=@Documented)
>          Integer foo = 1;
>          try {
>              MyBlackHole.blackHole(foo);
>          } catch (RuntimeException e) {
>              throw e;
>          }
>      }
> }
>
>
>
> pool[4] : class name utf8 index = 22
> pool[5] : class name utf8 index = 24
> pool[6] : class name utf8 index = 27
> pool[7] : utf8 = <init>
> pool[8] : utf8 = ()V
> pool[9] : utf8 = Code
> pool[10] : utf8 = LineNumberTable
> pool[11] : utf8 = StackMapTable
> pool[12] : class name utf8 index = 24
> pool[13] : class name utf8 index = 28
> pool[14] : class name utf8 index = 22
> pool[15] : utf8 = SourceFile
> pool[16] : utf8 = ClassDepsParserTest.java
> pool[17] : descriptor (TAN) utf8 index = 8 = ()V
> pool[18] : class name utf8 index = 28
> pool[19] : descriptor (TAN) utf8 index = 30 = null
> pool[20] : class name utf8 index = 31
> pool[21] : descriptor (TAN) utf8 index = 34 = null
> pool[22] : utf8 = java/lang/RuntimeException
> pool[23] : class name utf8 index = 35
> pool[24] : utf8 = net/jadecy/code/ClassDepsParserTest$MyMethodCodeInitBlock
> pool[25] : utf8 = MyMethodCodeInitBlock
> pool[26] : utf8 = InnerClasses
> pool[27] : utf8 = java/lang/Object
> pool[28] : utf8 = java/lang/Integer
> pool[29] : utf8 = valueOf
> pool[30] : utf8 = (I)Ljava/lang/Integer;
> pool[31] : utf8 = net/jadecy/code/ClassDepsParserTest$MyBlackHole
> pool[32] : utf8 = MyBlackHole
> pool[33] : utf8 = blackHole
> pool[34] : utf8 = (Ljava/lang/Object;)Z
> pool[35] : utf8 = net/jadecy/code/ClassDepsParserTest
>
> pool[4] : class name utf8 index = 36
> pool[5] : class name utf8 index = 38
> pool[6] : class name utf8 index = 40
> pool[7] : utf8 = <init>
> pool[8] : utf8 = ()V
> pool[9] : utf8 = Code
> pool[10] : utf8 = LineNumberTable
> pool[11] : utf8 = StackMapTable
> pool[12] : class name utf8 index = 38
> pool[13] : class name utf8 index = 41
> pool[14] : class name utf8 index = 36
> pool[15] : utf8 = RuntimeVisibleTypeAnnotations
> pool[16] : class name utf8 index = 42
> pool[17] : utf8 = A_TYPE_USE_R_COMPLEX
> pool[18] : utf8 = InnerClasses
> pool[19] : utf8 = Lnet/jadecy/code/ClassDepsParserTest$A_TYPE_USE_R_COMPLEX;
> pool[20] : utf8 = nbrClsArr
> pool[21] : utf8 = Ljava/lang/Long;
> pool[22] : utf8 = tooStrong
> pool[23] : utf8 =
> pool[24] : utf8 = rounding
> pool[25] : utf8 = Ljava/math/RoundingMode;
> pool[26] : utf8 = UNNECESSARY
> pool[27] : utf8 = doc
> pool[28] : utf8 = Ljava/lang/annotation/Documented;
> pool[29] : utf8 = SourceFile
> pool[30] : utf8 = ClassDepsParserTest.java
> pool[31] : descriptor (TAN) utf8 index = 8 = ()V
> pool[32] : class name utf8 index = 41
> pool[33] : descriptor (TAN) utf8 index = 44 = null
> pool[34] : class name utf8 index = 45
> pool[35] : descriptor (TAN) utf8 index = 48 = null
> pool[36] : utf8 = java/lang/RuntimeException
> pool[37] : class name utf8 index = 49
> pool[38] : utf8 =
> net/jadecy/code/ClassDepsParserTest$MyMethodCodeConstructor
> pool[39] : utf8 = MyMethodCodeConstructor
> pool[40] : utf8 = java/lang/Object
> pool[41] : utf8 = java/lang/Integer
> pool[42] : utf8 = net/jadecy/code/ClassDepsParserTest$A_TYPE_USE_R_COMPLEX
> pool[43] : utf8 = valueOf
> pool[44] : utf8 = (I)Ljava/lang/Integer;
> pool[45] : utf8 = net/jadecy/code/ClassDepsParserTest$MyBlackHole
> pool[46] : utf8 = MyBlackHole
> pool[47] : utf8 = blackHole
> pool[48] : utf8 = (Ljava/lang/Object;)Z
> pool[49] : utf8 = net/jadecy/code/ClassDepsParserTest
>
>
>
> -Jeff
>


More information about the jigsaw-dev mailing list