由ApacheCommon-BeanUtils1.8.3发现的Java HotSpot(TM)的Bug

文章描述了一个在Apache Commons BeanUtils 1.8.3版本中遇到的问题,即BeanUtils.copyProperties方法在处理实现泛型接口的类时无法正确复制属性值。此问题源于Java BeanInfo.getPropertyDescriptors方法在处理泛型时的缺陷。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ApacheCommon-BeanUtils1.8.3发现的JavaBug

 

org.apache.commons.beanutils.BeanUtils.copyProperties(Object dest, Object orig) throws IllegalAccessException, InvocationTargetException

 

 

 

我实际工程中orig参数是一个实现了泛型接口的类

 

public class BaseRole implements java.io.Serializable,Sortable<Long> {

 

    // Fields

    private Long sort;

   ...

    public Long getSort() {

       return this.sort;

    }

 

    public void setSort(Long sort) {

       this.sort = sort;

    }

 

}

 

 

接口为

 

 

public interface Sortable<T> {

 

    public T getSort();

 

}

 

  

这个BaseRole中的sort是无法通过BeanUtils.copyProperties 写入值的

 

原因是BeanUtils.copyProperties 底层使用了

 

BeanInfo beanInfo = Introspector.getBeanInfo(BaseRole.class);

PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();

 

Java在这里是有Bug

不能完全信任修复速度,1.6.0_05的BUG,我这跑的1.6.0_31仍未修复此问题!!

 

google 一下 BeanInfo.getPropertyDescriptors problem

第一个就是 sun 的Bug bolg

 

http://bugs.sun.com/view_bug.do?bug_id=6788525

 

Bug ID:

6788525

Votes

1

Synopsis

RFE: BeanInfo.getPropertyDescriptors() gets mixed up with generic bridge methods

Category

java:classes_beans

Reported Against

 

Release Fixed

 

State

3-Accepted, request for enhancement

Priority:

4-Low

Related Bugs

 

Submit Date

23-DEC-2008

Description

FULL PRODUCT VERSION :

java version "1.6.0_05"

Java(TM) SE Runtime Environment (build 1.6.0_05-b13)

Java HotSpot(TM) Client VM (build 10.0-b19, mixed mode)

 

 

ADDITIONAL OS VERSION INFORMATION :

 customer  Windows XP [versão 5.1.2600]

 

A DESCRIPTION OF THE PROBLEM :

If a JavaBean class has properties that are inherited from a generic superclass, java.beans.BeanInfo will find a PropertyDescriptor corresponding to synthetic bridge methods and not the actual typed methods.

 

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :

Create a generic superclass with a property (getter/setter pair) whose type is a type parameter. Create a parametrized subclass (a subclass with actual type arguments). Use java.beans.Introspector.getBeanInfo() to get a BeanInfo representing the subclass. Notice that the PropertyDescriptor that would correspond to the property (meaning, it's name is the same as the name of the property) has a type equal to the upper bound of the type parameter in the superclass, where we would expect it to have the corresponding type argument defined on the subclass.

 

This behavior is likely due to the Introspector finding synthetic bridge methods for the getter and setter instead of the actual methods.

 

(The Expected and Actual results below refer to the output of the sample code)

 

EXPECTED VERSUS ACTUAL BEHAVIOR :

EXPECTED -

class of type class java.lang.Class

foo of type class java.lang.String

 

ACTUAL -

class of type class java.lang.Class

foo of type class java.lang.Object

 

 

REPRODUCIBILITY :

This bug can be reproduced always.

 

---------- BEGIN SOURCE ----------

import java.beans.*;

 

class Super<T> {

         public T getFoo() {return null;}

         public void setFoo(T t) {}

}

 

class Sub extends Super<String> {

}

 

public class Main {

         public static void main(String[] args) throws IntrospectionException {

                 BeanInfo beanInfo = Introspector.getBeanInfo(Sub.class);

                

                 PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

                

                 for (PropertyDescriptor prop : propertyDescriptors) {

                          System.out.printf("%s of type %s\n", prop.getName(), prop.getPropertyType());

                 }

         }

}

---------- END SOURCE ----------

Posted Date : 2008-12-23 13:21:58.0

Work Around

N/A

Evaluation

N/A

Comments


Submitted On 30-DEC-2008 
I_AM_SUN

One more thing about this bug is that when interface Super<T> do not have set method. And Sub have this set method.

 

When called

  BeanInfo beanInfo = Introspector.getBeanInfo(Sub.class);

 

 

The PropertyDescriptor for foo do not have write method. But what I expected is although the interface Super do not have set method, but I am asking for the BeanInfo of Sub, its PropertyDescriptor should have writeMethod returned.

 



Submitted On 31-DEC-2009 

This is quite an annoying bug to run into and requires a bit of knowledge of the JLS to understand what is going on. I ran into this problem trying to get annotations of the method and was baffled as to why it wasn't working.




PLEASE NOTE: JDK6 is formerly known as Project Mustang

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值