spring-framework
spring-framework copied to clipboard
GenericTypeResolver resolves to an incorrect type if a class implements multiple generic interfaces depending on the order of definition of the interfaces.
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);
}
}