Skip to content

Commit b787a68

Browse files
committed
Avoid 'type mismatch' errors in ExtendedBeanInfo
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
1 parent ef143d3 commit b787a68

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

org.springframework.beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,9 @@ private void addOrUpdatePropertyDescriptor(PropertyDescriptor pd, String propert
219219
}
220220
}
221221
// update the existing descriptor's write method
222-
if (writeMethod != null) {
222+
if (writeMethod != null
223+
&& !(existingPD instanceof IndexedPropertyDescriptor &&
224+
!writeMethod.getParameterTypes()[0].isArray())) {
223225
existingPD.setWriteMethod(writeMethod);
224226
}
225227

org.springframework.beans/src/test/java/org/springframework/beans/ExtendedBeanInfoTests.java

+20-8
Original file line numberDiff line numberDiff line change
@@ -742,16 +742,28 @@ public boolean isTargetMethod() {
742742
assertThat(hasWriteMethodForProperty(ebi, "targetMethod"), is(false));
743743
}
744744

745-
static class X {
746-
public boolean isTargetMethod() {
747-
return false;
745+
@Test
746+
public void cornerSpr8937() throws IntrospectionException {
747+
@SuppressWarnings("unused") class A {
748+
public void setAddress(String addr){ }
749+
public void setAddress(int index, String addr) { }
750+
public String getAddress(int index){ return null; }
748751
}
749-
}
750752

751-
static class Y extends X {
752-
@Override
753-
public boolean isTargetMethod() {
754-
return false;
753+
{ // baseline. ExtendedBeanInfo needs to behave exactly like the following
754+
BeanInfo bi = Introspector.getBeanInfo(A.class);
755+
assertThat(hasReadMethodForProperty(bi, "address"), is(false));
756+
assertThat(hasWriteMethodForProperty(bi, "address"), is(false));
757+
assertThat(hasIndexedReadMethodForProperty(bi, "address"), is(true));
758+
assertThat(hasIndexedWriteMethodForProperty(bi, "address"), is(true));
759+
}
760+
{
761+
ExtendedBeanInfo bi = new ExtendedBeanInfo(Introspector.getBeanInfo(A.class));
762+
assertThat(hasReadMethodForProperty(bi, "address"), is(false));
763+
assertThat(hasWriteMethodForProperty(bi, "address"), is(false));
764+
assertThat(hasIndexedReadMethodForProperty(bi, "address"), is(true));
765+
assertThat(hasIndexedWriteMethodForProperty(bi, "address"), is(true));
755766
}
756767
}
768+
757769
}

0 commit comments

Comments
 (0)