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

Wrong property type after GC clears method refs

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 7u40
    • client-libs

      FULL PRODUCT VERSION :
      java version "1.7.0_40"
      Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
      Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      1. Given a base class A or an Interface with a generic Parameter <P> and a getter and setter method for an Attribute of type P.

      2. Given a derived class B extends A<AnyType> with a getter and setter method for AnyType which override the corresponding methods from the super class.

      After the the method references in the property descriptor have been cleared (by gc normally) and you retrive the property type once more the type is determined wrong.

      The following method list is a part of the result of B.class.getMethods()

      Method: public java.lang.Object B.getFoo(); isSyntetic=true
      Method: public java.lang.String B.getFoo(); isSyntetic=false
      Method: public void B.setFoo(java.lang.Object); isSyntetic=true
      Method: public void B.setFoo(java.lang.String); isSyntetic=false

      Unfortunately the method "getPublicDeclaredMethods" of class Introspector does not filter out all the Abstract and syntetic methods and becasue the method "internalFindMethod" of class Introspector now takes the first getter method it uses "public java.lang.Object B.getFoo()" to determine the property type which is wrong!

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      run the delivered test case

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      1. property type: class java.lang.String
      2. property type: class java.lang.String

      ACTUAL -
      property type (before clear ref): class java.lang.String
      property type (after clear ref): class java.lang.Object


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.beans.BeanInfo;
      import java.beans.IntrospectionException;
      import java.beans.Introspector;
      import java.beans.PropertyDescriptor;
      import java.lang.ref.Reference;
      import java.lang.reflect.Field;
      import java.lang.reflect.Method;

      class Super<T> {
      public T getFoo() {
      return null;
      }

      public void setFoo(T t) {
      }
      }

      class Sub extends Super<String> {
      @Override
      public String getFoo() {
      return null;
      }

      @Override
      public void setFoo(String t) {
      }
      }

      class Test {
      public void run() {
      PropertyDescriptor prop = getDescriptor("foo");

      for (Method aMethod : Sub.class.getMethods()) {
      System.out.println("Method: " + aMethod + "; isSyntetic=" + aMethod.isSynthetic());
      }

      System.out.println("");
      System.out.println("property type (before clear ref): " + prop.getPropertyType());
      clearMethodRef(prop, "readMethodRef");
      clearMethodRef(prop, "writeMethodRef");
      clearMethodRef(prop, "propertyTypeRef");
      System.out.println("property type (after clear ref): " + prop.getPropertyType());
      }

      private void clearMethodRef(PropertyDescriptor theProp, String theRefName) {
      try {
      Field aField = PropertyDescriptor.class.getDeclaredField(theRefName);

      aField.setAccessible(true);
      Reference<Method> aReference = (Reference<Method>) aField.get(theProp);
      aField.setAccessible(false);

      aReference.clear();
      }
      catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException theCause) {
      theCause.printStackTrace();
      }
      }

      private PropertyDescriptor getDescriptor(String theName) {
      try {
      BeanInfo beanInfo = Introspector.getBeanInfo(Sub.class);
      PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

      for (PropertyDescriptor prop : propertyDescriptors) {
      if (prop.getName().equals("foo")) {
      return prop;
      }
      }
      }
      catch (IntrospectionException theCause) {
      theCause.printStackTrace();
      }
      return null;
      }
      }

      public class Bug {
      public static void main(String[] args) {
      new Test().run();
      }

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

            malenkov Sergey Malenkov (Inactive)
            malenkov Sergey Malenkov (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: