Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CachedIntrospectionResults should build complete descriptor for setter/getter across interface hierarchy [SPR-16978] #21516

spring-projects-issues opened this issue Jun 26, 2018 · 0 comments
in: core type: enhancement


Copy link

@spring-projects-issues spring-projects-issues commented Jun 26, 2018

Petar Tahchiev opened SPR-16978 and commented

consider the following setup:

// code from spring-security
public interface UserDetails extends Serializable {
  Collection<? extends GrantedAuthority> getAuthorities();

  String getPassword();

  String getUsername();

  boolean isAccountNonExpired();

  boolean isAccountNonLocked();

  boolean isCredentialsNonExpired();

  boolean isEnabled();

public interface MyUserDetails extends UserDetails {
    Locale getLocale();

    void setLocale(final Locale locale);

    /* setters for super properties */

    void setUsername(String username);

    void setPassword(String password);

public interface CustomerDetails extends MyUsersDetails {
  String getPhone();

  void setPhone(String phone);

Now invoke BeanUtils.getPropertyDescriptor(CustomerDetails.class, "username"); and you will see that the returned PropertyDescriptor has correct writeMethod but the readMethod is null. As a result, if I try to submit a CustomerDetails form in spring-mvc
I get this error:

2018-06-26 18:13:33,604 org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/storefront].[dispatcherServlet] [https-jsse-nio-] ERROR: Servlet.service() for servlet [dispatcherServlet] in context with path [/storefront] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Method must not be null] with root cause
java.lang.IllegalArgumentException: Method must not be null
	at org.springframework.util.Assert.notNull(
	at org.springframework.core.MethodParameter.<init>(
	at org.springframework.core.MethodParameter.<init>(
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValue(
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(
	at org.springframework.validation.DataBinder.applyPropertyValues(
	at org.springframework.validation.DataBinder.doBind(
	at org.springframework.web.bind.WebDataBinder.doBind(
	at org.springframework.validation.DataBinder.bind(

I believe this is because in CachedIntrospectionResults a look goes through all super interfaces:

while (clazz != null && clazz != Object.class) {
     Class<?>[] ifcs = clazz.getInterfaces();
     for (Class<?> ifc : ifcs) {
              if (!ClassUtils.isJavaLanguageInterface(ifc)) {
                       for (PropertyDescriptor pd : getBeanInfo(ifc).getPropertyDescriptors()) {

until Object is reached and for each finds the property descriptor. However when it reaches MyUserDetails it finds the setter method and creates a PropertyDescriptor with null read method which is wrong because the read method is defined in the parent interface.

Affects: 5.0.7

Issue Links:

  • #18772 Java 8 default methods not detected as bean properties
  • #20869 CachedIntrospectionResults should use BeanInfoFactory when introspecting implemented interfaces
  • #21110 Consider caching interface-derived BeanInfo instances in CachedIntrospectionResults

Referenced from: commits bf5fe46

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
in: core type: enhancement
None yet

No branches or pull requests

2 participants