JDK-6676045 : StackOverFlowError during instantiation of generic type
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: generic
  • CPU: generic
  • Submitted: 2008-03-17
  • Updated: 2010-04-06
  • Resolved: 2008-10-09
Related Reports
Relates :  
Relates :  
Description
Description:
StackOverFlowError while compiling the following code during instantiation of generic type. This bug is directly related to bug 6651719 except for the change in the code where upper bound of S is MyClass<T,S>. Even using other parameterized bounds like java.util.LinkedList<T> crashes. Not sure if fix for bug 6651719 would resolve this issue. Hence filing this as a separate CR.
<code>
class TestClass {

    public  void method1(MyClass<? extends MyClass<?, ?>, ? extends MyClass<?, ?>> m1) {
         
    }
}
class MyClass<T extends S, S extends MyClass<T,S>> { // changing it to S extends java.util.List<T> crashes too
}
</code>
Compilation result is :
<output>
Following is the Error message:
The system is out of resources.
Consult the following stack trace for details.
java.lang.StackOverflowError
        at com.sun.tools.javac.code.Types$23.visitClassType(Types.java:2593)
        at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:568)
        at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3240)
        at com.sun.tools.javac.code.Types$23.visitWildcardType(Types.java:2616)
        at com.sun.tools.javac.code.Types$23.visitWildcardType(Types.java:2593)
        at com.sun.tools.javac.code.Type$WildcardType.accept(Type.java:430)
        at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3240)
        at com.sun.tools.javac.code.Types.hashCode(Types.java:2590)
        at com.sun.tools.javac.code.Types$TypePair.hashCode(Types.java:2363)
        at java.util.HashMap.put(HashMap.java:389)
        at java.util.HashSet.add(HashSet.java:217)
        at com.sun.tools.javac.code.Types$10.isCastableRecursive(Types.java:1103)
        at com.sun.tools.javac.code.Types$10.visitWildcardType(Types.java:1144)
        at com.sun.tools.javac.code.Types$10.visitWildcardType(Types.java:1090)
        at com.sun.tools.javac.code.Type$WildcardType.accept(Type.java:430)
        at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3183)
        at com.sun.tools.javac.code.Types.disjointType(Types.java:1087)
        at com.sun.tools.javac.code.Types.disjointTypes(Types.java:1070)
        at com.sun.tools.javac.code.Types$9.visitClassType(Types.java:979)
        at com.sun.tools.javac.code.Types$9.visitClassType(Types.java:885)
        at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:568)
        at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3183)
        at com.sun.tools.javac.code.Types.isCastable(Types.java:881)
        at com.sun.tools.javac.code.Types$9.visitWildcardType(Types.java:908)
        at com.sun.tools.javac.code.Types$9.visitWildcardType(Types.java:885)
        at com.sun.tools.javac.code.Type$WildcardType.accept(Type.java:430)
        at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3183)
        at com.sun.tools.javac.code.Types.isCastable(Types.java:881)
        at com.sun.tools.javac.code.Types.isCastable(Types.java:858)
        at com.sun.tools.javac.code.Types$10.isCastableRecursive(Types.java:1105)
        at com.sun.tools.javac.code.Types$10.visitWildcardType(Types.java:1144)
        at com.sun.tools.javac.code.Types$10.visitWildcardType(Types.java:1090)
        at com.sun.tools.javac.code.Type$WildcardType.accept(Type.java:430)
        at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3183)
        at com.sun.tools.javac.code.Types.disjointType(Types.java:1087)
        at com.sun.tools.javac.code.Types.disjointTypes(Types.java:1070)
        at com.sun.tools.javac.code.Types$9.visitClassType(Types.java:979)
        at com.sun.tools.javac.code.Types$9.visitClassType(Types.java:885)
        at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:568)
        at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3183)
        at com.sun.tools.javac.code.Types.isCastable(Types.java:881)
        at com.sun.tools.javac.code.Types$9.visitWildcardType(Types.java:908)
        at com.sun.tools.javac.code.Types$9.visitWildcardType(Types.java:885)
        at com.sun.tools.javac.code.Type$WildcardType.accept(Type.java:430)
        at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3183)
        at com.sun.tools.javac.code.Types.isCastable(Types.java:881)
        at com.sun.tools.javac.code.Types.isCastable(Types.java:858)
        at com.sun.tools.javac.code.Types$10.isCastableRecursive(Types.java:1105)
        at com.sun.tools.javac.code.Types$10.visitWildcardType(Types.java:1144)
        at com.sun.tools.javac.code.Types$10.visitWildcardType(Types.java:1090)
        at com.sun.tools.javac.code.Type$WildcardType.accept(Type.java:430)
        at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3183)
        at com.sun.tools.javac.code.Types.disjointType(Types.java:1087)
        at com.sun.tools.javac.code.Types.disjointTypes(Types.java:1070)
        at com.sun.tools.javac.code.Types$9.visitClassType(Types.java:979)
        at com.sun.tools.javac.code.Types$9.visitClassType(Types.java:885)
        at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:568)
        at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3183)
        at com.sun.tools.javac.code.Types.isCastable(Types.java:881)
        at com.sun.tools.javac.code.Types$9.visitWildcardType(Types.java:908)
        at com.sun.tools.javac.code.Types$9.visitWildcardType(Types.java:885)
        at com.sun.tools.javac.code.Type$WildcardType.accept(Type.java:430)
        at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3183)
        at com.sun.tools.javac.code.Types.isCastable(Types.java:881)
        at com.sun.tools.javac.code.Types.isCastable(Types.java:858)
        at com.sun.tools.javac.code.Types$10.isCastableRecursive(Types.java:1105)
        at com.sun.tools.javac.code.Types$10.visitWildcardType(Types.java:1144)
        at com.sun.tools.javac.code.Types$10.visitWildcardType(Types.java:1090)
        at com.sun.tools.javac.code.Type$WildcardType.accept(Type.java:430)
        at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3183)
        at com.sun.tools.javac.code.Types.disjointType(Types.java:1087)
        at com.sun.tools.javac.code.Types.disjointTypes(Types.java:1070)
        at com.sun.tools.javac.code.Types$9.visitClassType(Types.java:979)
        at com.sun.tools.javac.code.Types$9.visitClassType(Types.java:885)
        at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:568)
        at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3183)
        at com.sun.tools.javac.code.Types.isCastable(Types.java:881)
        at com.sun.tools.javac.code.Types$9.visitWildcardType(Types.java:908)
        at com.sun.tools.javac.code.Types$9.visitWildcardType(Types.java:885)
        at com.sun.tools.javac.code.Type$WildcardType.accept(Type.java:430)
</output>
<version>
/net/sqindia/export/disk09/jdk/7/latest/binaries/solsparc/bin/java -version
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b24)
Java HotSpot(TM) Client VM (build 12.0-b01, mixed mode)

bash-3.00$ uname -a
SunOS hrajan 5.10 Generic sun4u sparc SUNW,Sun-Blade-100

Comments
EVALUATION Fixed by 6651719 - same underlying cause, yet (slightly) different results. This time javac is enterning an infinite loop when executing a subtyping test in order to check type-parameter well-formedness. The loop is triggered by the fact that during checking of type arguments: ? extends MyClass<?,?>, ? extends MyClass<?,?> The wildcard type arguments are given new bounds that are the bounds of S and T respectively, where each occurrence of S and T has been replaced by actual type arguments: bound(1) = [S:=? extends MyClass<?,?>, T:=? extends MyClass<?,?>]bound(S) = ? extends MyClass<?,?> bound(1) = [S:=? extends MyClass<?,?>, T:=? extends MyClass<?,?>]bound(T) = MyClass<? extends MyClass<?,?>, ? extends MyClass<?,?>> Now, when javac checks bound well-formedness, the following test is issued: 1) is MyClass<?,?> castable to MyClass<?,?> 2) is MyClass<?,?> castable to MyClass<? extends MyClass<?,?>, ? extends MyClass<?,?>> The second test enters a loop because of the bounds defined above; as we can see from bound(2), javac ends up in rewriting the same test again and again (because while performing cast conversion javac needs to access bounds of wildcard type-arguments - which lead us back where we started from!). Another factor that is contributing to this problem is the fact that cast conversion (and in particular type-disjointness) is a bi-directional function; that is, in order to test type-disjointness of two types A and B, javac (roughly speaking) needs to execute two subtyping tests: A <: B B <: A This swapping causes the infinite loop - in other words it's impossible to reproduce this bug with a simple subtyping test.
09-10-2008