A DESCRIPTION OF THE PROBLEM :
Seems like javac generates invalid RuntimeVisibleTypeAnnotations for a compact record constructor for the record with components annotated with type-use annotations, when component type is nested class.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the provided java source, then check byte code generated for `Outer.Inner.Id` constructor.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Both parameters for Outer.Inner.Id constructor should have an annotation with `METHOD_FORMAL_PARAMETER` and `param_index` properties.
ACTUAL -
Below is the relevant part from the output of the JDK 25 `javap -v`
```
public demo.RuntimeVisibleTypeAnnotationsOuter$Inner$Id(java.lang.String, demo.RuntimeVisibleTypeAnnotationsOuter$Id);
descriptor: (Ljava/lang/String;Ldemo/RuntimeVisibleTypeAnnotationsOuter$Id;)V
flags: (0x0001) ACC_PUBLIC
Code:
stack=2, locals=3, args_size=3
0: aload_0
1: invokespecial #1 // Method java/lang/Record."<init>":()V
4: aload_0
5: aload_1
6: putfield #7 // Field value:Ljava/lang/String;
9: aload_0
10: aload_2
11: putfield #13 // Field outerId:Ldemo/RuntimeVisibleTypeAnnotationsOuter$Id;
14: return
LineNumberTable:
line 29: 0
line 30: 14
LocalVariableTable:
Start Length Slot Name Signature
0 15 0 this Ldemo/RuntimeVisibleTypeAnnotationsOuter$Inner$Id;
0 15 1 value Ljava/lang/String;
0 15 2 outerId Ldemo/RuntimeVisibleTypeAnnotationsOuter$Id;
MethodParameters:
Name Flags
value mandated
outerId mandated
RuntimeVisibleTypeAnnotations:
0: #30(): METHOD_FORMAL_PARAMETER, param_index=0
demo.RuntimeVisibleTypeAnnotationsOuter$Anno
1: #30(): FIELD
demo.RuntimeVisibleTypeAnnotationsOuter$Anno
```
The first annotation is the expected annotation for the first parameter.
The second annotation unexpectedly targets `FIELD` without any additional properties.
Tried to compile with JDK 21, 24 and 25 - the same result with bogus second annotation.
---------- BEGIN SOURCE ----------
package demo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public record RuntimeVisibleTypeAnnotationsOuter(
Id id
) {
public RuntimeVisibleTypeAnnotationsOuter {
}
public record Id(
String id
) {
}
public record Inner(
Id id
) {
public Inner {
}
public record Id(
@Anno String value,
RuntimeVisibleTypeAnnotationsOuter.@Anno Id outerId
) {
public Id {
}
}
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Anno {
}
}
---------- END SOURCE ----------
Seems like javac generates invalid RuntimeVisibleTypeAnnotations for a compact record constructor for the record with components annotated with type-use annotations, when component type is nested class.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the provided java source, then check byte code generated for `Outer.Inner.Id` constructor.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Both parameters for Outer.Inner.Id constructor should have an annotation with `METHOD_FORMAL_PARAMETER` and `param_index` properties.
ACTUAL -
Below is the relevant part from the output of the JDK 25 `javap -v`
```
public demo.RuntimeVisibleTypeAnnotationsOuter$Inner$Id(java.lang.String, demo.RuntimeVisibleTypeAnnotationsOuter$Id);
descriptor: (Ljava/lang/String;Ldemo/RuntimeVisibleTypeAnnotationsOuter$Id;)V
flags: (0x0001) ACC_PUBLIC
Code:
stack=2, locals=3, args_size=3
0: aload_0
1: invokespecial #1 // Method java/lang/Record."<init>":()V
4: aload_0
5: aload_1
6: putfield #7 // Field value:Ljava/lang/String;
9: aload_0
10: aload_2
11: putfield #13 // Field outerId:Ldemo/RuntimeVisibleTypeAnnotationsOuter$Id;
14: return
LineNumberTable:
line 29: 0
line 30: 14
LocalVariableTable:
Start Length Slot Name Signature
0 15 0 this Ldemo/RuntimeVisibleTypeAnnotationsOuter$Inner$Id;
0 15 1 value Ljava/lang/String;
0 15 2 outerId Ldemo/RuntimeVisibleTypeAnnotationsOuter$Id;
MethodParameters:
Name Flags
value mandated
outerId mandated
RuntimeVisibleTypeAnnotations:
0: #30(): METHOD_FORMAL_PARAMETER, param_index=0
demo.RuntimeVisibleTypeAnnotationsOuter$Anno
1: #30(): FIELD
demo.RuntimeVisibleTypeAnnotationsOuter$Anno
```
The first annotation is the expected annotation for the first parameter.
The second annotation unexpectedly targets `FIELD` without any additional properties.
Tried to compile with JDK 21, 24 and 25 - the same result with bogus second annotation.
---------- BEGIN SOURCE ----------
package demo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public record RuntimeVisibleTypeAnnotationsOuter(
Id id
) {
public RuntimeVisibleTypeAnnotationsOuter {
}
public record Id(
String id
) {
}
public record Inner(
Id id
) {
public Inner {
}
public record Id(
@Anno String value,
RuntimeVisibleTypeAnnotationsOuter.@Anno Id outerId
) {
public Id {
}
}
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Anno {
}
}
---------- END SOURCE ----------