### Question:
ReflectUtil { public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String property) { if (!propertyDescriptors.containsKey(clazz)) { getPropertyDescriptors(clazz); } return propertyDescriptors.get(clazz).get(property); } private  ReflectUtil(); static boolean isDefault(Method method); @SuppressWarnings("rawtypes") // this allows us to assign without casting static Class findClass(String name); static String toString(Annotation ann); static Collection<Method> getMethods(Class<?> clazz); static Collection<Field> getFields(Class<?> clazz); static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String property); static Method findAccessibleMethod(final Method m); static Field getField(Class<?> clazz, String property); static Object getDefaultValue(Class<?> clazz); static Set<Class<?>> getImplementedInterfaces(Class<?> clazz); static Type[] getActualTypeArguments(Class<?> clazz, Class<?> targetType); static PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz); static Method resolveBridgedReadMethod(PropertyDescriptor pd); static Method resolveBridgedWriteMethod(PropertyDescriptor pd); static Class<?> resolvePropertyType(PropertyDescriptor pd);  }### Answer:
@Test(groups = "fast") public void testCovariantProperty() { abstract class Base { abstract Object getId(); } class ROSub extends Base { protected String id; @Override public String getId() { return id; } } class RWSub extends ROSub { @SuppressWarnings("unused") public void setId(String id) { this.id = id; } } PropertyDescriptor pd = ReflectUtil.getPropertyDescriptor(ROSub.class, "id"); Assert.assertNotNull(pd.getReadMethod(), "Read method is null"); Assert.assertNull(pd.getWriteMethod(), "Write method is not null"); pd = ReflectUtil.getPropertyDescriptor(RWSub.class, "id"); Assert.assertNotNull(pd.getReadMethod(), "Read method is null"); Assert.assertNotNull(pd.getWriteMethod(), "Write method is null"); }