JDK-8331026 : Compact record constructor is missing generic type info on parameters
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 22
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2024-04-23
  • Updated: 2024-04-24
  • Resolved: 2024-04-24
Description
ADDITIONAL SYSTEM INFORMATION :
Java: openjdk 21.0.1 2023-10-17 LTS OpenJDK Runtime Environment Temurin-21.0.1+12 (build 21.0.1+12-LTS) OpenJDK 64-Bit Server VM Temurin-21.0.1+12 (build 21.0.1+12-LTS, mixed mode, sharing)

OS: Windows 11 on x86-64

A DESCRIPTION OF THE PROBLEM :
If a compact constructor is added to a record, that record's reflective Constructor object loses the generic type info on its Parameter objects.

See also: https://github.com/adoptium/adoptium-support/issues/1025

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached JUnit5 test case.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
All tests pass.
ACTUAL -
The "compact" test fails. The other tests pass.

---------- BEGIN SOURCE ----------
import java.lang.reflect.Type;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class RecordParameterTest {
	public static List<String> fieldWithExpectedType;
	public static Type expected;

	@BeforeAll
	static void determineExpectedType() throws NoSuchFieldException {
		expected = RecordParameterTest.class.getField("fieldWithExpectedType").getGenericType();
	}

	record ImplicitConstructor(List<String> arg){}

	record CompactConstructor(List<String> arg) {
		CompactConstructor { }
	}

	record CanonicalConstructor(List<String> arg) {
		CanonicalConstructor(List<String> arg) {
			this.arg = arg;
		}
	}

	@Test
	void implicit() {
		assertEquals(expected, firstConstructorParameterType(ImplicitConstructor.class));
	}

	@Test
	void compact() {
		assertEquals(expected, firstConstructorParameterType(CompactConstructor.class));
	}

	@Test
	void canonical() {
		assertEquals(expected, firstConstructorParameterType(CanonicalConstructor.class));
	}

	static Type firstConstructorParameterType(Class<?> c) {
		return c.getDeclaredConstructors()[0].getParameters()[0].getParameterizedType();
	}
}
---------- END SOURCE ----------

FREQUENCY : always



Comments
The observations on Windows 11: JDK 22: Passed all tests. Close as not an issue.
24-04-2024