JDK-8224012 : AnnotatedType implementations of hashCode() lead to StackOverflowError
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 12,13
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2019-05-15
  • Updated: 2019-08-07
  • Resolved: 2019-05-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 13 JDK 14
13 b23Fixed 14Fixed
Related Reports
Relates :  
Description
JDK-8058202 introduced hashCode() and equals() methods for the inner class implementations of AnnotatedType.

The implementations of hashCode() accumulate the hash codes of its elements. But the data structures are cyclic, which makes this simple traversal an endless recursion.

The problem can be easily reproduced, for example with 

    public static void main(String[] args) {
        Object[] intf = Enum.class.getAnnotatedInterfaces();
        Objects.hash(intf);
    }

The repeated stack trace elements in the StackOverflowError are
	at java.base/sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl.hashCode(AnnotatedTypeFactory.java:506)
	at java.base/java.util.Arrays.hashCode(Arrays.java:4706)
	at java.base/java.util.Objects.hash(Objects.java:147)
	at java.base/sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeVariableImpl.hashCode(AnnotatedTypeFactory.java:417)
	at java.base/java.util.Arrays.hashCode(Arrays.java:4706)
	at java.base/java.util.Objects.hash(Objects.java:147)
	at java.base/sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl.hashCode(AnnotatedTypeFactory.java:506)

The implementations of equals() follow the same pattern as the implementations of hashCode() and therefore probably have the same problem.
Comments
Review thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-May/060472.html
29-05-2019

Candidate fix: diff -r a978d86ac389 src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java Mon May 20 17:29:44 2019 -0700 +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java Tue May 21 22:34:47 2019 -0700 @@ -393,29 +393,22 @@ return (TypeVariable)getType(); } - // For toString, the declaration of a type variable should + // The declaration of a type variable should // including information about its bounds, etc. However, the // use of a type variable should not. For that reason, it is - // acceptable for the toString implementation of + // acceptable for the toString and hashCode implementations of // AnnotatedTypeVariableImpl to use the inherited - // implementation from AnnotatedTypeBaseImpl. + // implementations from AnnotatedTypeBaseImpl. @Override public boolean equals(Object o) { if (o instanceof AnnotatedTypeVariable) { AnnotatedTypeVariable that = (AnnotatedTypeVariable) o; - return equalsTypeAndAnnotations(that) && - Arrays.equals(getAnnotatedBounds(), that.getAnnotatedBounds()); + return equalsTypeAndAnnotations(that); } else { return false; } } - - @Override - public int hashCode() { - return baseHashCode() ^ - Objects.hash((Object[])getAnnotatedBounds()); - } } private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl Before sending out fore view, will first compare other AnnotatedType implementations in AnnotatedTypeFactory.java in corresponding ones in src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/* to identify and fix other analogous problems with equals/hashCode.
22-05-2019