diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java b/org.springframework.beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java index ef9a3a9414..211d1803ec 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java @@ -131,19 +131,13 @@ class ExtendedBeanInfo implements BeanInfo { Method indexedReadMethod = ipd.getIndexedReadMethod(); Method indexedWriteMethod = ipd.getIndexedWriteMethod(); // has the setter already been found by the wrapped BeanInfo? - if (indexedWriteMethod != null - && indexedWriteMethod.getName().equals(method.getName())) { - // yes -> copy it, including corresponding getter method (if any -- may be null) - this.addOrUpdatePropertyDescriptor(pd, propertyName, readMethod, writeMethod, indexedReadMethod, indexedWriteMethod); - continue ALL_METHODS; - } - // has a getter corresponding to this setter already been found by the wrapped BeanInfo? - if (indexedReadMethod != null - && indexedReadMethod.getName().equals(getterMethodNameFor(propertyName)) - && indexedReadMethod.getReturnType().equals(method.getParameterTypes()[1])) { - this.addOrUpdatePropertyDescriptor(pd, propertyName, readMethod, writeMethod, indexedReadMethod, method); - continue ALL_METHODS; + if (!(indexedWriteMethod != null + && indexedWriteMethod.getName().equals(method.getName()))) { + indexedWriteMethod = method; } + // yes -> copy it, including corresponding getter method (if any -- may be null) + this.addOrUpdatePropertyDescriptor(pd, propertyName, readMethod, writeMethod, indexedReadMethod, indexedWriteMethod); + continue ALL_METHODS; } // the INDEXED setter method was not found by the wrapped BeanInfo -> add a new PropertyDescriptor // for it. no corresponding INDEXED getter was detected, so the 'indexed read method' parameter is null. @@ -293,6 +287,16 @@ class ExtendedBeanInfo implements BeanInfo { writeMethod, propertyName, ex.getMessage())); // fall through -> add property descriptor as best we can } + if (pd instanceof IndexedPropertyDescriptor) { + ((IndexedPropertyDescriptor)pd).setIndexedReadMethod(indexedReadMethod); + try { + ((IndexedPropertyDescriptor)pd).setIndexedWriteMethod(indexedWriteMethod); + } catch (IntrospectionException ex) { + logger.debug(format("Could not add indexed write method [%s] for property [%s]. Reason: %s", + indexedWriteMethod, propertyName, ex.getMessage())); + // fall through -> add property descriptor as best we can + } + } this.propertyDescriptors.add(pd); } } diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/ExtendedBeanInfoTests.java b/org.springframework.beans/src/test/java/org/springframework/beans/ExtendedBeanInfoTests.java index ea4e783305..2049039a03 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/ExtendedBeanInfoTests.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/ExtendedBeanInfoTests.java @@ -34,6 +34,7 @@ import java.lang.reflect.Method; import org.junit.Test; import org.springframework.beans.ExtendedBeanInfo.PropertyDescriptorComparator; +import org.springframework.core.JdkVersion; import org.springframework.util.ClassUtils; import test.beans.TestBean; @@ -429,11 +430,12 @@ public class ExtendedBeanInfoTests { } BeanInfo bi = Introspector.getBeanInfo(C.class); - BeanInfo ebi = new ExtendedBeanInfo(Introspector.getBeanInfo(C.class)); assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true)); // interesting! standard Inspector picks up non-void return types on indexed write methods by default - assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(true)); + assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(trueUntilJdk17())); + + BeanInfo ebi = new ExtendedBeanInfo(Introspector.getBeanInfo(C.class)); assertThat(hasIndexedReadMethodForProperty(ebi, "foos"), is(true)); assertThat(hasIndexedWriteMethodForProperty(ebi, "foos"), is(true)); @@ -456,13 +458,12 @@ public class ExtendedBeanInfoTests { assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true)); assertThat(hasWriteMethodForProperty(bi, "foos"), is(false)); // again as above, standard Inspector picks up non-void return types on indexed write methods by default - assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(true)); + assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(trueUntilJdk17())); BeanInfo ebi = new ExtendedBeanInfo(Introspector.getBeanInfo(C.class)); assertThat(hasIndexedReadMethodForProperty(bi, "foos"), is(true)); assertThat(hasWriteMethodForProperty(bi, "foos"), is(true)); - // again as above, standard Inspector picks up non-void return types on indexed write methods by default assertThat(hasIndexedWriteMethodForProperty(bi, "foos"), is(true)); assertThat(hasIndexedReadMethodForProperty(ebi, "foos"), is(true)); @@ -550,17 +551,17 @@ public class ExtendedBeanInfoTests { assertThat(hasReadMethodForProperty(bi, "dateFormat"), is(false)); assertThat(hasWriteMethodForProperty(bi, "dateFormat"), is(false)); assertThat(hasIndexedReadMethodForProperty(bi, "dateFormat"), is(false)); - assertThat(hasIndexedWriteMethodForProperty(bi, "dateFormat"), is(true)); + assertThat(hasIndexedWriteMethodForProperty(bi, "dateFormat"), is(trueUntilJdk17())); ExtendedBeanInfo ebi = new ExtendedBeanInfo(bi); assertThat(hasReadMethodForProperty(bi, "dateFormat"), is(false)); - assertThat(hasWriteMethodForProperty(bi, "dateFormat"), is(true)); + assertThat(hasWriteMethodForProperty(bi, "dateFormat"), is(false)); assertThat(hasIndexedReadMethodForProperty(bi, "dateFormat"), is(false)); - assertThat(hasIndexedWriteMethodForProperty(bi, "dateFormat"), is(true)); + assertThat(hasIndexedWriteMethodForProperty(bi, "dateFormat"), is(trueUntilJdk17())); assertThat(hasReadMethodForProperty(ebi, "dateFormat"), is(false)); - assertThat(hasWriteMethodForProperty(ebi, "dateFormat"), is(true)); + assertThat(hasWriteMethodForProperty(ebi, "dateFormat"), is(false)); assertThat(hasIndexedReadMethodForProperty(ebi, "dateFormat"), is(false)); assertThat(hasIndexedWriteMethodForProperty(ebi, "dateFormat"), is(true)); } @@ -663,6 +664,10 @@ public class ExtendedBeanInfoTests { return false; } + private boolean trueUntilJdk17() { + return JdkVersion.getMajorJavaVersion() < JdkVersion.JAVA_17; + } + @Test public void reproSpr8806() throws IntrospectionException {