Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8041630

Exception while constructing BeanInfo using java.beans.Introspector

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.7.0_45"
      Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
      Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      Introspector.getBeanInfo throws AssertionError(cause: java.beans.IntrospectionException) when trying to get BeanInfo for a class that specializes return type of indexed getter method in sub-class.

      I would expect that indexed and non-indexed properties should be handled by Introspector using similar logic.
      In the attached example BeanInfo is generated for class with single non-indexed property,
      but fails with AssertionError if we modify the property to be indexed.

      I have found similar bug report with a fix for java.beans.PropertyDescriptor:
      http://hg.openjdk.java.net/jdk7u/jdk7u-dev/jdk/rev/ef26b6c8264d

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run example code

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      All assertions should pass
      ACTUAL -
      AssertionError is thrown from IndexedPropertyDescriptor line 480

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "main" java.lang.AssertionError: java.beans.IntrospectionException: type mismatch between indexed read and indexed write methods: value
      at java.beans.IndexedPropertyDescriptor.<init>(IndexedPropertyDescriptor.java:480)
      at java.beans.Introspector.processPropertyDescriptors(Introspector.java:647)
      at java.beans.Introspector.getTargetPropertyInfo(Introspector.java:543)
      at java.beans.Introspector.getBeanInfo(Introspector.java:418)
      at java.beans.Introspector.getBeanInfo(Introspector.java:163)
      at com.pivotcapital.test.IntrospectorIssue.main(IntrospectorIssue.java:10)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:606)
      at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
      Caused by: java.beans.IntrospectionException: type mismatch between indexed read and indexed write methods: value
      at java.beans.IndexedPropertyDescriptor.findIndexedPropertyType(IndexedPropertyDescriptor.java:387)
      at java.beans.IndexedPropertyDescriptor.setIndexedReadMethod(IndexedPropertyDescriptor.java:215)
      at java.beans.IndexedPropertyDescriptor.<init>(IndexedPropertyDescriptor.java:471)
      ... 10 more

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.beans.*;

      public class IntrospectorIssue {

          public static void main(String[] args) {
              // Getting BeanInfo for class with non-indexed property
              try {
                  final BeanInfo beanInfo = Introspector.getBeanInfo(TestClass1.class);
                  final PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
                  assert descriptors.length == 2;
                  final PropertyDescriptor classPropertyDescriptor = descriptors[0];
                  assert "class".equals(classPropertyDescriptor.getName());

                  final PropertyDescriptor valuePropertyDescriptor = descriptors[1];
                  assert "value".equals(valuePropertyDescriptor.getName());
                  assert Number.class.equals(valuePropertyDescriptor.getPropertyType());
              } catch (Throwable e) {
                  e.printStackTrace();
              }

              // Getting BeanInfo for class with indexed property
              try {
                  final BeanInfo beanInfo = Introspector.getBeanInfo(TestClass2.class);
                  final PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
                  assert descriptors.length == 2;
                  final PropertyDescriptor classPropertyDescriptor = descriptors[0];
                  assert "class".equals(classPropertyDescriptor.getName());

                  final PropertyDescriptor valuePropertyDescriptor = descriptors[1];
                  assert "value".equals(valuePropertyDescriptor.getName());
                  assert Number.class.equals(valuePropertyDescriptor.getPropertyType());
              } catch (Throwable e) {
                  e.printStackTrace();
              }
          }

          public static abstract class AbstractTestClass1 {

              public Number getValue() {
                  return null;
              }

              public void setValue(Number value) {

              }
          }

          public static class TestClass1 extends AbstractTestClass1 {

              public Long getValue() {
                  return null;
              }

              public void setValue(Number value) {

              }

          }

          public static abstract class AbstractTestClass2 {

              public Number getValue(int i) {
                  return null;
              }

              public void setValue(int i, Number value) {

              }
          }

          public static class TestClass2 extends AbstractTestClass2 {

              public Long getValue(int i) {
                  return null;
              }

              public void setValue(int i, Number value) {

              }

          }
      }
      ---------- END SOURCE ----------

            alitvinov Anton Litvinov (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: