Index: src/main/java/org/jboss/resteasy/core/MethodInjectorImpl.java =================================================================== --- src/main/java/org/jboss/resteasy/core/MethodInjectorImpl.java (revision 892) +++ src/main/java/org/jboss/resteasy/core/MethodInjectorImpl.java (working copy) @@ -15,6 +15,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; /** * @author Bill Burke @@ -54,8 +55,22 @@ Type[] genericParameterTypes = Types.getGenericParameterTypesOfGenericInterfaceMethod(root, method); for (int i = 0; i < method.getParameterTypes().length; i++) { - Class type = method.getParameterTypes()[i]; - Type genericType = genericParameterTypes[i]; + Class type; + Type genericType; + + // the parameter type might be a type variable defined in a superclass + if (genericParameterTypes[i] instanceof TypeVariable) + { + // try to find out the value of the type variable + genericType = Types.getActualValueOfTypeVariable(root, (TypeVariable)genericParameterTypes[i]); + type = Types.getRawType(genericType); + } + else + { + type = method.getParameterTypes()[i]; + genericType = genericParameterTypes[i]; + } + Annotation[] annotations = method.getParameterAnnotations()[i]; params[i] = InjectorFactoryImpl.getParameterExtractor(root, method, type, genericType, annotations, factory); } Index: src/main/java/org/jboss/resteasy/util/Types.java =================================================================== --- src/main/java/org/jboss/resteasy/util/Types.java (revision 892) +++ src/main/java/org/jboss/resteasy/util/Types.java (working copy) @@ -264,4 +264,42 @@ } return null; } + + /** + * Finds an actual value of a type variable. The method looks in a class hierarchy for a class defining the variable + * and returns the value if present. + * @param clazz + * @param typeVariable + * @return actual type of the type variable + */ + public static Type getActualValueOfTypeVariable(Class clazz, TypeVariable typeVariable) + { + if (typeVariable.getGenericDeclaration() instanceof Class) + { + Class classDeclaringTypeVariable = (Class) typeVariable.getGenericDeclaration(); + + // find the generic version of classDeclaringTypeVariable + while (clazz.getSuperclass() != null) + { + if (clazz.getSuperclass().equals(classDeclaringTypeVariable)) + { + // found it + ParameterizedType parameterizedSuperclass = (ParameterizedType) clazz.getGenericSuperclass(); + + for (int i = 0; i < classDeclaringTypeVariable.getTypeParameters().length; i++) + { + TypeVariable tv = classDeclaringTypeVariable.getTypeParameters()[i]; + if (tv.equals(typeVariable)) + { + return parameterizedSuperclass.getActualTypeArguments()[i]; + } + } + } + + clazz = clazz.getSuperclass(); + } + } + + throw new RuntimeException("Unable to determine value of type parameter " + typeVariable); + } }