• Java 17
  • Spring boot 3.0.0

I was trying to invoke setWrappedInstance to set a new object on BeanWrapperImpl, but I got NullPointerException after invoking getPropertyValue.

Below is how I reproduce this issue: LightSaber, Person, Jedi define:

public interface LightSaber {
    void getLightSaber();
}
import lombok.Data;

@Data
public class Person implements LightSaber {
    private String firstName;
    private String lastName;

    @Override
    public void getLightSaber() {
        System.out.println("get light saber");
    }
}
import lombok.Data;

@Data
public class Jedi extends Person {
}

My test code:

    @Test
    void setBeanWrapperInstance_mockSetInstanceTwice() {
        BeanWrapperImpl beanWrapper = new BeanWrapperImpl(Jedi.class);

        LightSaber luke = new Jedi(){{setFirstName("Luke"); setLastName("Skywalker");}};
        beanWrapper.setWrappedInstance(luke);
        Assertions.assertEquals("Luke", beanWrapper.getPropertyValue("firstName"));

        LightSaber anakin = new Jedi(){{setFirstName("Anakin"); setLastName("Skywalker");}};
        beanWrapper.setWrappedInstance(anakin);

        Assertions.assertEquals("Anakin", beanWrapper.getPropertyValue("firstName"));
    }

Error Output:

java.lang.NullPointerException: Cannot invoke "java.beans.BeanDescriptor.getBeanClass()" because the return value of "java.beans.BeanInfo.getBeanDescriptor()" is null

                at org.springframework.beans.CachedIntrospectionResults.getBeanClass(CachedIntrospectionResults.java:383)
                at org.springframework.beans.BeanWrapperImpl.setIntrospectionClass(BeanWrapperImpl.java:151)
                at org.springframework.beans.BeanWrapperImpl.setWrappedInstance(BeanWrapperImpl.java:142)
                at org.springframework.beans.AbstractNestablePropertyAccessor.setWrappedInstance(AbstractNestablePropertyAccessor.java:184)
                at com.jiechang.demo.service.BeanWrapperImplTest.setBeanWrapperInstance_mockSetInstanceTwice(BeanWrapperImplTest.java:19)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
                at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.base/java.lang.reflect.Method.invoke(Method.java:568)
                at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
                at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
                at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
                at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
...