Uploaded image for project: 'Commons BeanUtils'
  1. Commons BeanUtils
  2. BEANUTILS-541

FluentPropertyBeanIntrospector caches corrupted writeMethod (two subclasses)

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Blocker
    • Resolution: Fixed
    • 1.9.0, 1.9.1, 1.9.2, 1.9.3, 1.9.4
    • 2.0.0, 1.9.5
    • Bean / Property Utils
    • None

    Description

      There is an issue in FluentPropertyBeanIntrospector (at line 144 for 1.9.3), it caches wrong writeMethod in the static cache of java.beans.Introspector when base class (with chained setter) has at least two subclasses. Simple snippet to reproduce:

      import org.apache.commons.beanutils.FluentPropertyBeanIntrospector;
      import org.apache.commons.beanutils.PropertyUtilsBean;
      
      public class BeanUtilsTest {
      
          public static void main(String[] args) throws Exception {
              PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
              propertyUtilsBean.addBeanIntrospector(new FluentPropertyBeanIntrospector());
      
              // invert if condition and it will succeed
              if (true) {
                  // fails
      
                  SubTypeA subTypeA = new SubTypeA();
                  //subTypeA.setField("name");
                  propertyUtilsBean.setProperty(subTypeA, "field", "name");
      
                  // uncomment this line and the failure will be handled (workaround)
                  //java.beans.Introspector.flushCaches();
      
                  SubTypeB subTypeB = new SubTypeB();
                  //subTypeB.setField("name");
                  propertyUtilsBean.setProperty(subTypeB, "field", "name");
              } else {
                  // the same as above, but reverse order - success
      
                  SubTypeB subTypeB = new SubTypeB();
                  //subTypeB.setField("name");
                  propertyUtilsBean.setProperty(subTypeB, "field", "name");
      
                  SubTypeA subTypeA = new SubTypeA();
                  //subTypeA.setField("name");
                  propertyUtilsBean.setProperty(subTypeA, "field", "name");
              }
          }
      
          public static class BaseType {
      
              private String field;
      
              public BaseType setField(String objectName) {
                  this.field = objectName;
                  // pay attention - setter returns self object (not void)
                  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 {
      
          }
      }
      

       
      It is critical, because wrong information is stored globally unless explicit Introspector.flushCaches (Introspector.flushFromCaches) is called.

      Failure stacktrace:

      Exception in thread "main" java.lang.IllegalArgumentException: org.jeasy.random.BeanUtilsTest$SubTypeB is not assignable from org.jeasy.random.BeanUtilsTest$SubTypeA
      	at org.apache.commons.beanutils.MethodUtils.getAccessibleMethod(MethodUtils.java:793)
      	at org.apache.commons.beanutils.PropertyUtilsBean.getWriteMethod(PropertyUtilsBean.java:1319)
      	at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:2094)
      	at org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1915)
      	at org.apache.commons.beanutils.PropertyUtilsBean.setProperty(PropertyUtilsBean.java:2022)
      	at org.jeasy.random.BeanUtilsTest.main(BeanUtilsTest.java:44)
      

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              seregamorph Sergey Chernov
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: