FasterXML / java-classmate

Library for introspecting generic type information of types, member/static methods, fields. Especially useful for POJO/Bean introspection.
http://fasterxml.com
Apache License 2.0
258 stars 42 forks source link

Self types causes StackOverflowError with MemberResolver #4

Closed yschimke closed 13 years ago

yschimke commented 13 years ago

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)
cowtowncoder commented 13 years ago

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

cowtowncoder commented 13 years ago

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

yschimke commented 13 years ago

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

cowtowncoder commented 13 years ago

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

cowtowncoder commented 13 years ago

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

cowtowncoder commented 13 years ago

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.

cowtowncoder commented 13 years ago

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.