FasterXML/java-classmate

Self types causes StackOverflowError with MemberResolver

yschimke opened this issue · 7 comments

The following Junit test code fails with a StackOverflow

public class ComplexSelfType<T, V extends ComplexSelfType<T, V>> {
}

public class ClassUsingComplexSelfType {
  public <T, V extends ComplexSelfType<T, V>> V complexMap(V input) {
    return null;
  }
}

@Test
public void testStraightClassMate() {
  TypeResolver typeResolver = new TypeResolver();
  MemberResolver memberResolver = new MemberResolver(typeResolver);

  ResolvedType t = typeResolver.resolve(ClassUsingComplexSelfType.class);
  ResolvedMethod[] resolvedMethods = memberResolver.resolve(t, null, null).getMemberMethods();
}

Exception is below (for 0.5.3)

java.lang.StackOverflowError
  at com.fasterxml.classmate.util.ClassKey.<init>(ClassKey.java:19)
  at com.fasterxml.classmate.TypeResolver._fromClass(TypeResolver.java:337)
  at com.fasterxml.classmate.TypeResolver._fromAny(TypeResolver.java:316)
  at com.fasterxml.classmate.TypeResolver._fromVariable(TypeResolver.java:462)
  at com.fasterxml.classmate.TypeResolver._fromAny(TypeResolver.java:325)
  at com.fasterxml.classmate.TypeResolver._fromParamType(TypeResolver.java:424)
  at com.fasterxml.classmate.TypeResolver._fromAny(TypeResolver.java:319)

Ok thanks. ClassMate should be able to resolve self-references, so this is obvously a bug.

Ok, added unit test; need to figure out exactly how to untangle handling next. :)

It also fails for the simpler case <T extends Comparable<T>>

That is odd, as I did test case of Enum types (which are self-referential). Well, glad that it was found at any rate.

Ok, looks like self-refs are ok for classes, but not for methods with local generic type declarations.

More specifically, only class self-references (like "Class Enum<E extends Enum>") are handle currently. Need to figure out a way to do the same for type variables.

Ok: fixed; needed to add local binding for unresolved type variables (roughly equivalent to finding binding to Object.class) before trying to resolve lower bound which is used to resolve something better. Now passes unit tests and appears to function as expected.

Also: will probably release patch version (0.5.4) tonight, since this is the only open bug for now.