This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-beanutils.git

commit 3e1923bad3c249569817634d261b22d37451f45f
Author: Gary Gregory <[email protected]>
AuthorDate: Sun Aug 23 09:46:58 2026 -0400

    Skip static methods in FluentPropertyBeanIntrospector and mapped lookup
    
    Add missing unit tests that could have been in PR #437.
    
    The tests explicitly cover the mixed static/instance accessor cases that
    were missing:
    
    Mapped property with a static getter but instance setter: read method is
    ignored, write method is used.
    
    Mapped property with an instance getter but static setter: read method
    is used, write method is ignored.
    
    Fluent introspector with a static and an instance setter for the same
    property name: the instance setter is chosen and the property remains
    writable.
---
 .../FluentPropertyBeanIntrospectorTest.java        | 32 ++++++++++++++++
 .../commons/beanutils2/MappedPropertyTest.java     | 44 +++++++++++++++++-----
 .../commons/beanutils2/MappedPropertyTestBean.java | 22 +++++++++--
 3 files changed, 85 insertions(+), 13 deletions(-)

diff --git 
a/src/test/java/org/apache/commons/beanutils2/FluentPropertyBeanIntrospectorTest.java
 
b/src/test/java/org/apache/commons/beanutils2/FluentPropertyBeanIntrospectorTest.java
index 1cc6ae13..fac98bcd 100644
--- 
a/src/test/java/org/apache/commons/beanutils2/FluentPropertyBeanIntrospectorTest.java
+++ 
b/src/test/java/org/apache/commons/beanutils2/FluentPropertyBeanIntrospectorTest.java
@@ -46,6 +46,23 @@ class FluentPropertyBeanIntrospectorTest {
         }
     }
 
+    public static final class MixedSetterBean {
+        public static void setMixed(final Integer v) {
+            // static setter should be ignored
+        }
+
+        private String value;
+
+        public String getMixed() {
+            return value;
+        }
+
+        public MixedSetterBean setMixed(final String v) {
+            this.value = v;
+            return this;
+        }
+    }
+
     public static final class StaticSetterBean {
         private static String staticValue;
 
@@ -138,6 +155,21 @@ class FluentPropertyBeanIntrospectorTest {
         assertNull(props.get("uRI"), "Should not find mis-capitalized 
property");
     }
 
+    /**
+     * Tests that an instance setter is used when a static setter with the 
same name exists.
+     */
+    @Test
+    void testIntrospectionMixedStaticInstanceSetter() throws Exception {
+        final PropertyUtilsBean pu = new PropertyUtilsBean();
+        pu.addBeanIntrospector(new FluentPropertyBeanIntrospector());
+        final Map<String, PropertyDescriptor> props = 
createDescriptorMap(pu.getPropertyDescriptors(MixedSetterBean.class));
+        final PropertyDescriptor pd = fetchDescriptor(props, "mixed");
+        assertNotNull(pd.getReadMethod(), "No read method for mixed");
+        assertNotNull(pd.getWriteMethod(), "Instance setter should be found");
+        
assertFalse(java.lang.reflect.Modifier.isStatic(pd.getWriteMethod().getModifiers()),
 "Write method should not be static");
+        assertTrue(pu.isWriteable(new MixedSetterBean(), "mixed"), "mixed 
should be writeable");
+    }
+
     /**
      * Tests that static methods are not treated as write methods.
      */
diff --git 
a/src/test/java/org/apache/commons/beanutils2/MappedPropertyTest.java 
b/src/test/java/org/apache/commons/beanutils2/MappedPropertyTest.java
index f6d898bc..f5a561c5 100644
--- a/src/test/java/org/apache/commons/beanutils2/MappedPropertyTest.java
+++ b/src/test/java/org/apache/commons/beanutils2/MappedPropertyTest.java
@@ -111,6 +111,18 @@ class MappedPropertyTest {
         assertNotNull(desc.getMappedWriteMethod(), "Setter is missing");
     }
 
+    /**
+     * Test instance getter is used but static setter is ignored
+     */
+    @Test
+    void testInstanceGetterStaticSetter() throws Exception {
+        final String property = "instanceGetterStaticSetter";
+        final Class<?> clazz = MappedPropertyTestBean.class;
+        final MappedPropertyDescriptor desc = new 
MappedPropertyDescriptor(property, clazz);
+        assertNotNull(desc.getMappedReadMethod(), "Instance getter should be 
found");
+        assertNull(desc.getMappedWriteMethod(), "Static setter should be 
ignored");
+    }
+
     /**
      * Test Interface with mapped property
      */
@@ -225,16 +237,6 @@ class MappedPropertyTest {
         assertThrows(IntrospectionException.class, () -> new 
MappedPropertyDescriptor(property, clazz));
     }
 
-    /**
-     * Test static mapped accessors are ignored
-     */
-    @Test
-    void testStaticMapped() {
-        final String property = "staticMapped";
-        final Class<?> clazz = MappedPropertyTestBean.class;
-        assertThrows(IntrospectionException.class, () -> new 
MappedPropertyDescriptor(property, clazz));
-    }
-
     /**
      * Test 'protected' method in parent
      */
@@ -256,4 +258,26 @@ class MappedPropertyTest {
         assertNotNull(desc.getMappedReadMethod(), "Getter is missing");
         assertNotNull(desc.getMappedWriteMethod(), "Setter is missing");
     }
+
+    /**
+     * Test static getter is ignored but instance setter is used
+     */
+    @Test
+    void testStaticGetterInstanceSetter() throws Exception {
+        final String property = "staticGetterInstanceSetter";
+        final Class<?> clazz = MappedPropertyTestBean.class;
+        final MappedPropertyDescriptor desc = new 
MappedPropertyDescriptor(property, clazz);
+        assertNull(desc.getMappedReadMethod(), "Static getter should be 
ignored");
+        assertNotNull(desc.getMappedWriteMethod(), "Instance setter should be 
found");
+    }
+
+    /**
+     * Test static mapped accessors are ignored
+     */
+    @Test
+    void testStaticMapped() {
+        final String property = "staticMapped";
+        final Class<?> clazz = MappedPropertyTestBean.class;
+        assertThrows(IntrospectionException.class, () -> new 
MappedPropertyDescriptor(property, clazz));
+    }
 }
diff --git 
a/src/test/java/org/apache/commons/beanutils2/MappedPropertyTestBean.java 
b/src/test/java/org/apache/commons/beanutils2/MappedPropertyTestBean.java
index 69d7f56c..a28cf111 100644
--- a/src/test/java/org/apache/commons/beanutils2/MappedPropertyTestBean.java
+++ b/src/test/java/org/apache/commons/beanutils2/MappedPropertyTestBean.java
@@ -26,21 +26,33 @@ import java.util.Map;
 
 public class MappedPropertyTestBean {
 
-    private final Map<Object, Object> map = new HashMap<>();
-    private final Map<Object, Object> myMap = new HashMap<>();
-
+    public static String getStaticGetterInstanceSetter(final String key) {
+        return null;
+    }
     public static String getStaticMapped(final String key) {
         return "static-" + key;
     }
 
+    public static void setInstanceGetterStaticSetter(final String key, final 
String value) {
+        // static setter should be ignored
+    }
+
     public static void setStaticMapped(final String key, final String value) {
         // empty
     }
 
+    private final Map<Object, Object> map = new HashMap<>();
+
+    private final Map<Object, Object> myMap = new HashMap<>();
+
     public Long getDifferentTypes(final String key) {
         return Long.valueOf(((Number) map.get(key)).longValue());
     }
 
+    public String getInstanceGetterStaticSetter(final String key) {
+        return (String) map.get(key);
+    }
+
     public String getInvalidGetter(final String key, final String other) {
         return (String) map.get(key);
     }
@@ -104,4 +116,8 @@ public class MappedPropertyTestBean {
         map.put(key, value);
     }
 
+    public void setStaticGetterInstanceSetter(final String key, final String 
value) {
+        map.put(key, value);
+    }
+
 }

Reply via email to