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

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


The following commit(s) were added to refs/heads/1.X by this push:
     new 8ac9a644 BEANUTILS-541 - FluentPropertyBeanIntrospector caches 
corrupted writeMethod (#69)
8ac9a644 is described below

commit 8ac9a644162eca9de2b6ab867c50ec1070c39f07
Author: Sergey Chernov <[email protected]>
AuthorDate: Sun Apr 14 14:42:03 2024 +0200

    BEANUTILS-541 - FluentPropertyBeanIntrospector caches corrupted writeMethod 
(#69)
---
 pom.xml                                            |  4 ++
 .../beanutils/FluentPropertyBeanIntrospector.java  | 11 +++
 .../commons/beanutils/bugs/Jira541TestCase.java    | 78 ++++++++++++++++++++++
 3 files changed, 93 insertions(+)

diff --git a/pom.xml b/pom.xml
index 0714c2bf..04c0d13b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -339,6 +339,10 @@
       <name>Melloware</name>
       <email />
     </contributor>
+    <contributor>
+      <name>Sergey Chernov</name>
+      <email></email>
+    </contributor>
   </contributors>
 
   <dependencies>
diff --git 
a/src/main/java/org/apache/commons/beanutils/FluentPropertyBeanIntrospector.java
 
b/src/main/java/org/apache/commons/beanutils/FluentPropertyBeanIntrospector.java
index ab447eb0..aa7a7c1b 100644
--- 
a/src/main/java/org/apache/commons/beanutils/FluentPropertyBeanIntrospector.java
+++ 
b/src/main/java/org/apache/commons/beanutils/FluentPropertyBeanIntrospector.java
@@ -141,6 +141,10 @@ public class FluentPropertyBeanIntrospector implements 
BeanIntrospector {
                         
icontext.addPropertyDescriptor(createFluentPropertyDescritor(
                                 m, propertyName));
                     } else if (pd.getWriteMethod() == null) {
+                        // We change statically cached PropertyDescriptor, it 
may affect
+                        // other subclasses of targetClass supertype.
+                        // See BEANUTILS-541 for more details.
+                        
clearDescriptorsCacheHierarchy(icontext.getTargetClass().getSuperclass());
                         pd.setWriteMethod(m);
                     }
                 } catch (final IntrospectionException e) {
@@ -152,6 +156,13 @@ public class FluentPropertyBeanIntrospector implements 
BeanIntrospector {
         }
     }
 
+    private static void clearDescriptorsCacheHierarchy(Class<?> cls) {
+        if (cls != null && cls != Object.class) {
+            Introspector.flushFromCaches(cls);
+            clearDescriptorsCacheHierarchy(cls.getSuperclass());
+        }
+    }
+
     /**
      * Derives the name of a property from the given set method.
      *
diff --git 
a/src/test/java/org/apache/commons/beanutils/bugs/Jira541TestCase.java 
b/src/test/java/org/apache/commons/beanutils/bugs/Jira541TestCase.java
new file mode 100644
index 00000000..55871263
--- /dev/null
+++ b/src/test/java/org/apache/commons/beanutils/bugs/Jira541TestCase.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.beanutils.bugs;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.commons.beanutils.FluentPropertyBeanIntrospector;
+import org.apache.commons.beanutils.PropertyUtilsBean;
+import org.junit.Test;
+
+/**
+ * Fix BEANUTILS-541
+ *
+ * @see <a 
href="https://issues.apache.org/jira/browse/BEANUTILS-541";>https://issues.apache.org/jira/browse/BEANUTILS-541</a>
+ */
+public class Jira541TestCase {
+
+    private static final String FIELD_NAME = "field";
+    private static final String FIELD_VALUE = "name";
+
+    @Test
+    public void testFluentBeanIntrospectorOnOverriddenSetter() throws 
Exception {
+        PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
+        propertyUtilsBean.addBeanIntrospector(new 
FluentPropertyBeanIntrospector());
+
+        // note: we should setProperty first on SubTypeA (with overridden 
setter), then on subTypeB
+        // but not vice versa
+        SubTypeA subTypeA = new SubTypeA();
+        propertyUtilsBean.setProperty(subTypeA, FIELD_NAME, FIELD_VALUE);
+
+        SubTypeB subTypeB = new SubTypeB();
+        propertyUtilsBean.setProperty(subTypeB, FIELD_NAME, FIELD_VALUE);
+
+        assertEquals(FIELD_VALUE, subTypeA.getField());
+        assertEquals(FIELD_VALUE, subTypeB.getField());
+    }
+
+    public static class BaseType {
+
+        private String field;
+
+        public BaseType setField(String objectName) {
+            this.field = objectName;
+            return this;
+        }
+
+        public String getField() {
+            return field;
+        }
+    }
+
+    public static class SubTypeA extends BaseType {
+
+        @Override
+        public SubTypeA setField(String field) {
+            super.setField(field);
+            return this;
+        }
+    }
+
+    public static class SubTypeB extends BaseType {
+
+    }
+}

Reply via email to