-
Bug
-
Resolution: Fixed
-
P3
-
6u18, 7
-
generic
-
generic
-
Verified
FULL PRODUCT VERSION :
java version " 1.6.0_18 "
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
When migrating from JDK 5 and JDK 6, to JDK 7, there is a change in the building of the read-write property pairs in the PropertyDescriptor. The system is using a third party library that boils down to a call to Introspector.getBeanInfo(beanInstance.getClass()) to get the BeanInfo which is then interrogated for its properties via beanInfo.getPropertyDescriptors().
If the read method is defined on the target class but the write method is declared in the base class, the generated PropertyDescriptor does not have the write method. The change in behavior is limited to properties that are defined between the target class and a super class in the class hierarchy. This seems to only affect properties that involve generics. Both the read and write methods are available if both members are defined in the same class or if their type does not involve generics.
When debugging, the full collection of methods can be seen on the BeanInfo but the write method is not in the properties for the affected properties. Also, the methods are not bridge methods and the types appear consistent for the read and write methods.
In the attached example, propertyA and propertyD will have read methods but no write method whereas propertyB, propertyC, and propertyE have both a read and write method in the PropertyDescriptor.
REGRESSION. Last worked in version 6u31
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
execute attached class
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Property named class has a read method and does not have a write method.
Property named propertyA has a read method and has a write method.
Property named propertyB has a read method and has a write method.
Property named propertyC has a read method and has a write method.
Property named propertyD has a read method and has a write method.
Property named propertyE has a read method and has a write method.
ACTUAL -
Property named class has a read method and does not have a write method.
Property named propertyA has a read method and does not have a write method.
Property named propertyB has a read method and has a write method.
Property named propertyC has a read method and has a write method.
Property named propertyD has a read method and does not have a write method.
Property named propertyE has a read method and has a write method.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.List;
public final class PropertyDescriptorExample
{
public static void main(String... args)
{
try
{
final PropertyDescriptorExample example = new PropertyDescriptorExample();
example.doIt();
}
catch (final Exception ignored)
{
}
}
public void doIt() throws Exception
{
final ChildBean<String> bean = new ChildBean<String>();
final BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
final PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (final PropertyDescriptor propertyDescriptor : propertyDescriptors)
{
System.out.println(String.format( " Property named %s %s a read method and %s a write method. " ,
propertyDescriptor.getName(),
(null != propertyDescriptor.getReadMethod()) ? " has " : " does not have " ,
(null != propertyDescriptor.getWriteMethod()) ? " has " : " does not have " ));
}
}
public final class ChildBean<E extends Comparable<E>> extends BaseBean<E>
{
@Override
public List<E> getPropertyA()
{
return super.getPropertyA();
}
@Override
public Object getPropertyC()
{
return super.getPropertyC();
}
@Override
public E getPropertyD()
{
return super.getPropertyD();
}
}
public class BaseBean<T extends Comparable<T>>
{
private List<T> _propertyA;
private List<T> _propertyB;
private Object _propertyC;
private T _propertyD;
private T _propertyE;
protected List<T> getPropertyA()
{
return _propertyA;
}
public void setPropertyA(final List<T> propertyA)
{
_propertyA = propertyA;
}
public List<? extends T> getPropertyB()
{
return _propertyB;
}
public void setPropertyB(final List<T> propertyB)
{
_propertyB = propertyB;
}
protected Object getPropertyC()
{
return _propertyC;
}
public void setPropertyC(final Object propertyC)
{
_propertyC = propertyC;
}
protected T getPropertyD()
{
return _propertyD;
}
public void setPropertyD(final T propertyD)
{
_propertyD = propertyD;
}
public T getPropertyE()
{
return _propertyE;
}
public void setPropertyE(final T propertyE)
{
_propertyE = propertyE;
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Declare getter and setter at the same level in the class hierarchy. If one needs overridden for any reason, also override the other half of the read-write pair if the method type involves generics.
java version " 1.6.0_18 "
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
When migrating from JDK 5 and JDK 6, to JDK 7, there is a change in the building of the read-write property pairs in the PropertyDescriptor. The system is using a third party library that boils down to a call to Introspector.getBeanInfo(beanInstance.getClass()) to get the BeanInfo which is then interrogated for its properties via beanInfo.getPropertyDescriptors().
If the read method is defined on the target class but the write method is declared in the base class, the generated PropertyDescriptor does not have the write method. The change in behavior is limited to properties that are defined between the target class and a super class in the class hierarchy. This seems to only affect properties that involve generics. Both the read and write methods are available if both members are defined in the same class or if their type does not involve generics.
When debugging, the full collection of methods can be seen on the BeanInfo but the write method is not in the properties for the affected properties. Also, the methods are not bridge methods and the types appear consistent for the read and write methods.
In the attached example, propertyA and propertyD will have read methods but no write method whereas propertyB, propertyC, and propertyE have both a read and write method in the PropertyDescriptor.
REGRESSION. Last worked in version 6u31
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
execute attached class
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Property named class has a read method and does not have a write method.
Property named propertyA has a read method and has a write method.
Property named propertyB has a read method and has a write method.
Property named propertyC has a read method and has a write method.
Property named propertyD has a read method and has a write method.
Property named propertyE has a read method and has a write method.
ACTUAL -
Property named class has a read method and does not have a write method.
Property named propertyA has a read method and does not have a write method.
Property named propertyB has a read method and has a write method.
Property named propertyC has a read method and has a write method.
Property named propertyD has a read method and does not have a write method.
Property named propertyE has a read method and has a write method.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.List;
public final class PropertyDescriptorExample
{
public static void main(String... args)
{
try
{
final PropertyDescriptorExample example = new PropertyDescriptorExample();
example.doIt();
}
catch (final Exception ignored)
{
}
}
public void doIt() throws Exception
{
final ChildBean<String> bean = new ChildBean<String>();
final BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
final PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (final PropertyDescriptor propertyDescriptor : propertyDescriptors)
{
System.out.println(String.format( " Property named %s %s a read method and %s a write method. " ,
propertyDescriptor.getName(),
(null != propertyDescriptor.getReadMethod()) ? " has " : " does not have " ,
(null != propertyDescriptor.getWriteMethod()) ? " has " : " does not have " ));
}
}
public final class ChildBean<E extends Comparable<E>> extends BaseBean<E>
{
@Override
public List<E> getPropertyA()
{
return super.getPropertyA();
}
@Override
public Object getPropertyC()
{
return super.getPropertyC();
}
@Override
public E getPropertyD()
{
return super.getPropertyD();
}
}
public class BaseBean<T extends Comparable<T>>
{
private List<T> _propertyA;
private List<T> _propertyB;
private Object _propertyC;
private T _propertyD;
private T _propertyE;
protected List<T> getPropertyA()
{
return _propertyA;
}
public void setPropertyA(final List<T> propertyA)
{
_propertyA = propertyA;
}
public List<? extends T> getPropertyB()
{
return _propertyB;
}
public void setPropertyB(final List<T> propertyB)
{
_propertyB = propertyB;
}
protected Object getPropertyC()
{
return _propertyC;
}
public void setPropertyC(final Object propertyC)
{
_propertyC = propertyC;
}
protected T getPropertyD()
{
return _propertyD;
}
public void setPropertyD(final T propertyD)
{
_propertyD = propertyD;
}
public T getPropertyE()
{
return _propertyE;
}
public void setPropertyE(final T propertyE)
{
_propertyE = propertyE;
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Declare getter and setter at the same level in the class hierarchy. If one needs overridden for any reason, also override the other half of the read-write pair if the method type involves generics.
- duplicates
-
JDK-7192955 Introspector overide PropertyDescriptor for generic type field defined in super class
- Resolved