JDK 13 RFR of JDK-8224012: AnnotatedType implementations of hashCode() lead to StackOverflowError

Joe Darcy joe.darcy at oracle.com
Wed May 29 05:52:20 UTC 2019


Hello,

Please review the changes to address:

     JDK-8224012: AnnotatedType implementations of hashCode() lead to 
StackOverflowError
     http://cr.openjdk.java.net/~darcy/8224012.1/

As discussed in the JBS entry, this is a follow-up issue to fix an 
implementation flaw in JDK-8058202: "AnnotatedType implementations don't 
override toString(), equals(), hashCode()".

In brief, the equals/hashCode methods in the AnnotatedTypeBaseImpl 
classes are updated to avoid possible circularities  in their calling 
structure. As described in more detail below, a comparison is made 
against analogous implementation types in the 
sun.reflect.generics.reflectiveObjects package 
(src/java.base/share/classes/sun/reflect/generics/reflectiveObjects).

A brief summary for some additional context, the original core 
reflection had various "getFoo" methods in java.lang.Class and the 
classes in the classes of the java.lang.reflect package. In JDK 5.0, 
many of these methods had a "getGenericFoo" sibling method added to 
preserve behavioral compatibility of the original method while providing 
access to information about generic declarations. In JDK 8, 
"getAnnotatedFoo" methods were added, as new sibling methods to support 
type annotations, alongside the existing getFoo and getGenericFoo 
methods. Semantically, the getAnnotatedfoo methods are 
"getGenericAnnotatedFoo, but (fortunately) that verbose naming 
convention was not chosen. A family of AnnoatedBar classes was also 
added in JDK 8 to allow annotation on interior structures to be modeled, 
such as a method returning "Set<List<@Quux String>>".

Some notes in the implementation, the hierarchy of annotated type 
implementation classes is housed in 
src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java. 
The nested classes are subtypes of AnnotatedTypeBaseImpl. The building 
blocks of equals and hashCode in that parent type examine the underlying 
type, annotations, and (possibly null) owner type.

The four subtypes and the information they examine in their 
equals/hashCode methods:

     AnnotatedArrayType: base information + component type;
         GenericArrayTypeImpl.java compares component type

     AnnotatedParameterizedType: base information + actual type arguments;
         ParameterizedTypeImpl.java compares owner type, raw type, and 
actual type arguments

     AnnotatedTypeVariable: base information (*changed to omit checking 
of bounds*);
         TypeVariableImpl.java compares generic declaration and name

     AnnotatedWildcardType: base information + upper bounds + lower bounds;
         WildcardTypeImpl.java compares upper bounds and lower bounds

The newly added test cases quickly stackoverflow when run against the 
old implementation.

Thanks,

-Joe



More information about the core-libs-dev mailing list