--- BasicBeanDescription.orig 2009-10-30 19:52:12.000000000 -0400 +++ BasicBeanDescription.java 2009-11-11 13:50:21.000000000 -0500 @@ -3,6 +3,8 @@ import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.*; import org.codehaus.jackson.map.AnnotationIntrospector; @@ -427,16 +429,55 @@ * If so, should throw an exception */ AnnotatedMethod old = results.put(propName, am); - if (old != null) { - String oldDesc = old.getFullName(); - String newDesc = am.getFullName(); - throw new IllegalArgumentException("Conflicting setter definitions for property \""+propName+"\": "+oldDesc+" vs "+newDesc); + if (hasCorrespondingGetterOfSameType(old)) { + results.put(propName, old); } + // if (old != null) { + // String oldDesc = old.getFullName(); + // String newDesc = am.getFullName(); + // throw new IllegalArgumentException("Conflicting setter definitions for property \""+propName+"\": "+oldDesc+" vs "+newDesc); + // } } return results; } + private Method getGetter(Class clazz, String sName) { + try { + return clazz.getMethod(sName, new Class[] {}); + } catch (NoSuchMethodException e) { + return null; + } + } + + private boolean hasCorrespondingGetterOfSameType(AnnotatedMethod am) + { + String propertyName = am.getName().substring(3); + Class declaringClass = am.getAnnotated().getDeclaringClass(); + try { + Method getter = getGetter(declaringClass, "get" + propertyName); + if (getter == null) { + getter = getGetter(declaringClass, "is"); + } + if (getter == null) { + // TODO - what to do here? + return true; + } + + Type parameterType = am.getParameterType(0); + if (parameterType instanceof ParameterizedType) { + parameterType = ((ParameterizedType) parameterType).getRawType(); + } + if (parameterType instanceof Class) { + return ((Class) parameterType).isAssignableFrom(getter.getReturnType()); + } else { + throw new RuntimeException("Expecting a class at this point."); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + /** * Method used to locate the method of introspected class that