Skip to content

Commit

Permalink
Avoid 'type mismatch' errors in ExtendedBeanInfo
Browse files Browse the repository at this point in the history
Prior to this commit, ExtendedBeanInfo would add non-indexed write
methods without consideration for the presence of indexed read/write
methods, which is invalid per the JavaBeans spec and per the behavior
of java.beans.Introspector.  That is, a method with the signature

    void setFoo(Foo foo)

Should never be registered as a write method if the following method
signature is also present in the class

    void setFoo(int i, Foo foo)

In most cases, this oversight caused no problems, but in certain
situations where a bean actually contains such a mismatch of methods,
"type mismatch" errors were thrown when ExtendedBeanInfo attempted the
illegal addition against the underlying property descriptor.

The implementation is now more careful about checking the parameter type
of write methods -- if the property descriptor in question is an
IndexedPropertyDescriptor, i.e. has an indexed write method, then any
non-indexed write method candidate must have a single *array* parameter,
which conforms to the spec and to Introspector behavior.

Issue: SPR-8937
  • Loading branch information
cbeams committed Feb 13, 2012
1 parent ef143d3 commit b787a68
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,9 @@ private void addOrUpdatePropertyDescriptor(PropertyDescriptor pd, String propert
}
}
// update the existing descriptor's write method
if (writeMethod != null) {
if (writeMethod != null
&& !(existingPD instanceof IndexedPropertyDescriptor &&
!writeMethod.getParameterTypes()[0].isArray())) {
existingPD.setWriteMethod(writeMethod);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,16 +742,28 @@ public boolean isTargetMethod() {
assertThat(hasWriteMethodForProperty(ebi, "targetMethod"), is(false));
}

static class X {
public boolean isTargetMethod() {
return false;
@Test
public void cornerSpr8937() throws IntrospectionException {
@SuppressWarnings("unused") class A {
public void setAddress(String addr){ }
public void setAddress(int index, String addr) { }
public String getAddress(int index){ return null; }
}
}

static class Y extends X {
@Override
public boolean isTargetMethod() {
return false;
{ // baseline. ExtendedBeanInfo needs to behave exactly like the following
BeanInfo bi = Introspector.getBeanInfo(A.class);
assertThat(hasReadMethodForProperty(bi, "address"), is(false));
assertThat(hasWriteMethodForProperty(bi, "address"), is(false));
assertThat(hasIndexedReadMethodForProperty(bi, "address"), is(true));
assertThat(hasIndexedWriteMethodForProperty(bi, "address"), is(true));
}
{
ExtendedBeanInfo bi = new ExtendedBeanInfo(Introspector.getBeanInfo(A.class));
assertThat(hasReadMethodForProperty(bi, "address"), is(false));
assertThat(hasWriteMethodForProperty(bi, "address"), is(false));
assertThat(hasIndexedReadMethodForProperty(bi, "address"), is(true));
assertThat(hasIndexedWriteMethodForProperty(bi, "address"), is(true));
}
}

}

0 comments on commit b787a68

Please sign in to comment.