Affects: 5.3.20
GenericTypeResolver#resolveVariable(TypeVariable<?> typeVariable, ResolvableType contextType)
eventually resorts to recursively resolving the type of typeVariable
by iterating over contextType.getInterfaces()
.
The first generic interface will hit the "// Fallback to bounds"-branch in ResolvableType#resolveType()
even though this interface (and its generic type) might have nothing to do with typeVariable
.
Workaround for us: omitting the type bound "F extends Number" at FooService
Minimal working example:
Output:
java.lang.Integer
java.lang.Number
Expected output:
java.lang.Integer
java.lang.Integer
Code:
import java.lang.reflect.Type;
import org.springframework.core.GenericTypeResolver;
public class Main {
public static class BaseParam {
}
public static class FooParam extends BaseParam {
}
public interface FooService<F extends Number> {
default void foo(F f) {
// ...
}
}
public interface BarService<B> {
default void bar(B b) {
// ...
}
}
public static class FooBarService implements FooService<Integer>, BarService<String> {
}
public static class BarFooService implements BarService<String>, FooService<Integer> {
}
public static void printType(Class<?> cls) {
Type f = FooService.class.getTypeParameters()[0];
System.out.println(GenericTypeResolver.resolveType(f, cls).getTypeName());
}
public static void main(String[] args) throws Exception {
printType(FooBarService.class);
printType(BarFooService.class);
}
}
Comment From: snicoll
@arneschweenbs with the current version of the framework, the output is the expected one. I've moved that sample (thanks for that!) to a unit test to make sure this case is covered.