Skip to content

SimpleBeanInfoFactory fails to reliably resolve read/write methods in type hierarchies with unresolved generics #36019

@zhanhcs

Description

@zhanhcs

Overview

  • jdk21
  • Spring 6.2.11

In the following case, the setId(int id) method is inconsistent with the generic type String, and since it implements two interfaces, random copying failures may occur.

The methods of the IModel class cannot change their order; doing so may prevent this issue from being reproduced.

public class BeanUtilsCopyPropertiesTests {

    public static class BaseModel<T> {

        public BaseModel() {
        }

        private T id;

        /**
         * @return the id
         */
        public T getId() {
            return id;
        }

        /**
         * @param id the id to set
         */
        public void setId(T id) {
            this.id = id;
        }
    }

    interface IModel<T>{
        void setId(T id);
        T getId();
    }
    interface A<T>  extends IModel<T>{
    }
    interface B<T>  extends IModel<T>{
    }

    public static class User extends BaseModel<String> implements A<String>,B<String> {

        public User() {
            super();
        }
        @Override
        public String getId() {
            return super.getId();
        }
        public void setId(int id) {
            setId(String.valueOf(id));
        }
    }

    @org.junit.jupiter.api.Test
    public void testCopyFailed(){
        User source = new User();
        source.setId(1);
        User target = new User();
        BeanUtils.copyProperties(source, target);

        assertEquals(source.getId(), target.getId());
    }

}

Analysis

Root cause : PropertyDescriptorUtils

This is caused by the inconsistent order returned by the Class#getMethods.

	public static Collection<? extends PropertyDescriptor> determineBasicProperties(Class<?> beanClass)
			throws IntrospectionException {
		Map<String, BasicPropertyDescriptor> pdMap = new TreeMap<>();
		for (Method method : beanClass.getMethods()) {

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)status: backportedAn issue that has been backported to maintenance branchestype: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions