RFR: 8347826: Introspector shows wrong method list after 8071693 [v4]

Sergey Bylokhov serb at openjdk.org
Tue Feb 11 06:18:09 UTC 2025


On Thu, 6 Feb 2025 14:13:50 GMT, Roman Marchenko <rmarchenko at openjdk.org> wrote:

>> Fixed `com.sun.beans.introspect.MethodInfo#MethodOrder` to make `Introspector.addMethod()` working properly when filtering methods out.
>> 
>> Also fixed the test, and added the approptiate test case.
>
> Roman Marchenko has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Update test/jdk/java/beans/Introspector/DefaultMethodBeanPropertyTest.java
>   
>   Co-authored-by: Aleksandr Zvegintsev <77687766+azvegint at users.noreply.github.com>

I also would like to discuss the next small example.


import java.beans.*;
import java.lang.reflect.Method;

interface Parent1<T> {
    T getValue();
}

interface Parent2 {
    Runnable getValue();
}

interface Parent3 extends Parent2, Parent1<Object> {
    Runnable getValue();
}

abstract class Child implements Parent3 {
    public void setValue(Runnable value) {
    }
}

public class BeansMainInt {
    public static void main(String[] args) throws Exception {
        BeanInfo beanInfo = Introspector.getBeanInfo(Child.class);
        for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
            Method writeMethod = pd.getWriteMethod();
            Method readMethod = pd.getReadMethod();
            System.out.println(pd.getName()+ ":\n ** " + pd.getPropertyType()
                    + "\n >> " + readMethod + "\n << " + writeMethod);
        }
    }
}



Before the JDK-8071693 the output is:
value:
 ** interface java.lang.Runnable
 >> null
 << public void Child.setValue(java.lang.Runnable)


Current output is(this patch did not change it):

value:
 ** class java.lang.Object
 >> public default java.lang.Object Parent3.getValue()
 << public void Child.setValue(java.lang.Runnable)


Is `default Parent3.getValue()` really supposed to be the writer for the "value" property, that looks suspicious?

If you replace interfaces with abstract classes then you will get the old output:



import java.beans.*;
import java.lang.reflect.Method;

abstract class Parent1<T> {
    abstract T getValue();
}

abstract class Parent2 {
    abstract Runnable getValue();
}

abstract class Parent3 extends Parent2 {
    abstract Runnable getValue();
}

abstract class Child extends Parent3 {
    public void setValue(Runnable value) {
    }
}

public class BeansMainInt {
    public static void main(String[] args) throws Exception {
        BeanInfo beanInfo = Introspector.getBeanInfo(Child.class);
        for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
            Method writeMethod = pd.getWriteMethod();
            Method readMethod = pd.getReadMethod();
            System.out.println(pd.getName()+ ":\n ** " + pd.getPropertyType()
                    + "\n >> " + readMethod + "\n << " + writeMethod);
        }
    }
}

value:
 ** interface java.lang.Runnable
 >> null
 << public void Child.setValue(java.lang.Runnable)

-------------

PR Comment: https://git.openjdk.org/jdk/pull/23443#issuecomment-2649891398


More information about the client-libs-dev mailing list