JDK-8225470 : Constructor.getParameterAnnotations does not include implicit enclosing param
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux_ubuntu
  • CPU: x86_64
  • Submitted: 2019-05-31
  • Updated: 2019-06-07
  • Resolved: 2019-06-07
Related Reports
Duplicate :  
Description
ADDITIONAL SYSTEM INFORMATION :
$ uname -a
Linux job 4.18.0-20-generic #21~18.04.1-Ubuntu SMP Wed May 8 08:43:37 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ java -version                                                                 ~
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-8u212-b03-0ubuntu1.18.04.1-b03)
OpenJDK 64-Bit Server VM (build 25.212-b03, mixed mode)


A DESCRIPTION OF THE PROBLEM :
Javadoc for Executable#getParameterAnnotations states that "Synthetic and mandated parameters (see explanation below), such as the outer "this" parameter to an inner class constructor will be represented in the returned array."
This is not true for the Constructor implementation.

And it breaks the Parameter.getDeclaredAnnotations call - it returns annotations of the next parameter and fails with index error on last parameter.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the provided source code

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
annotations = []
annotations = []
annotations = [@Scratch$Ann()]


parameter = Scratch arg0
parameter.getDeclaredAnnotations() = []

parameter = java.lang.String arg1
parameter.getDeclaredAnnotations() = []

parameter = java.lang.String arg2
parameter.getDeclaredAnnotations() = [@Scratch$Ann()]

ACTUAL -
annotations = []
annotations = [@Scratch$Ann()]


parameter = Scratch arg0
parameter.getDeclaredAnnotations() = []

parameter = java.lang.String arg1
parameter.getDeclaredAnnotations() = [@Scratch$Ann()]

parameter = java.lang.String arg2
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
	at java.lang.reflect.Parameter.getDeclaredAnnotations(Parameter.java:305)
	at Scratch.test(scratch_1.java:31)
	at Scratch.main(scratch_1.java:8)

---------- BEGIN SOURCE ----------
import java.lang.annotation.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
import java.util.Arrays;

class Scratch {
	public static void main(String[] args) {
		new Scratch().test();
	}

	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.PARAMETER)
	@interface Ann {}

	class Test {
		Test(String first, @Ann String second) {}
	}

	public void test() {

		Constructor<?> constructor = Test.class.getDeclaredConstructors()[0];

		for (Annotation[] annotations : constructor.getParameterAnnotations()) {
			System.out.println("annotations = " + Arrays.toString(annotations));
		}

		System.out.println("\n");

		for (Parameter parameter : constructor.getParameters()) {
			System.out.println("parameter = " + parameter);
			System.out.println("parameter.getDeclaredAnnotations() = " + Arrays.toString(parameter.getDeclaredAnnotations()));
			System.out.println();
		}
	}
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
When working with Parameter arrays you can check if `parameter.getDeclaringExecutable().getDeclaringClass().getEnclosingClass() != null` and get annotations 'from previous parameter' accordingly.


Comments
Issue is already fixed in JDk 9 and higher versions 8u212 - Fail 9 ea b171 - Fail 9 ea b172 - Pass <== Issue resolved here 9 GA - Pass 11.0.3 - Pass 13 ea 22 - Pass This issue is resolved in 9 ea b172, by JDK-8074977 Kindly upgrade your JDK to use JDK11 version to avoid this issue Closing as Duplicate of JDK-8074977
07-06-2019