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

Introspector throws NullPointerException for subclasses' mismatched get/setter

XMLWordPrintable

    • b12
    • x86_64
    • linux

        FULL PRODUCT VERSION :
        java version "1.8.0"
        Java(TM) SE Runtime Environment (build 1.8.0-b132)
        Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)


        A DESCRIPTION OF THE PROBLEM :
        java.beans.Introspector.getBeanInfo() throws a NullPointerException if you have a pair of getTer()/setTer() methods in a base class; and a pair of getTer()/setTer() methods in a subclass (or auto-generated proxy); and getTer() return type is not exactly the same as setTer() argument type (in my case, getTer() returns Set and setTer() only accepts some Set sub-interface).

        We caught that by using Introspector on javassist Proxies returned by Hibernate. We have our own set implementation but Hibernate demands the use of the java.util.Set, hence the mixed use of both that led to the discovery of this bug.

        See the code sample.

        REGRESSION. Last worked in version 7u45

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        See the code sample.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        Bean info is returned.
        ACTUAL -
        NullPointerException is being thrown.

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        Exception in thread "main" java.lang.NullPointerException
        at java.lang.Class.isAssignableFrom(Native Method)
        at java.beans.Introspector.isAssignable(Introspector.java:809)
        at java.beans.Introspector.processPropertyDescriptors(Introspector.java:705)
        at java.beans.Introspector.getTargetPropertyInfo(Introspector.java:553)
        at java.beans.Introspector.getBeanInfo(Introspector.java:428)
        at java.beans.Introspector.getBeanInfo(Introspector.java:262)
        at IntrospectorFail.main(IntrospectorFail.java:39)


        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.beans.Introspector;
        import java.util.Set;

        public class IntrospectorFail {
            public interface SetF<X> extends Set<X> { }

            public class Base {
                private SetF<Object> items;

                public Set<Object> getItems() {
                    return items;
                }

                public void setItems(SetF<Object> items) {
                    this.items = items;
                }
            }

            public class Child extends Base {
                public Set<Object> getItems() {
                    return super.getItems();
                }

                public void setItems(SetF<Object> items) {
                    super.setItems(items);
                }
            }

            public static void main(String[] args) throws Throwable {
                // OK
                Introspector.getBeanInfo(Base.class, Object.class, Introspector.USE_ALL_BEANINFO);
                // OK
                Introspector.getBeanInfo(Child.class, Base.class, Introspector.USE_ALL_BEANINFO);
                // BOOM
                Introspector.getBeanInfo(Child.class, Object.class, Introspector.USE_ALL_BEANINFO);
            }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        - Make sure getters' and setter' parameter/return class is exactly the same.
        - Use stopClass = getSuperclass() (not applicable if error manifests inside a library)

              malenkov Sergey Malenkov (Inactive)
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved: