Some properties of 3rd party provided class with inheritance relationship cannot be render to configuration metadata.

Versions

  • Spring Boot 2.3.0.RELEASE

Details

For example, following class provides from 3rd-party library:

Example 1

public class BaseConfig {
  private boolean boolValue;
  private int intValue;
  private final Nest nest = new Nest();
  // getter and setter ...
}
public class ChildConfig extends BaseConfig {
  private long longValue;
  private final NestInChild childNest = new NestInChild();
  // getter and setter ...
  public static class NestInChild {
    private boolean boolValue;
    private int intValue;
    // getter and setter ...
  }
}
  @Bean
  @ConfigurationProperties(prefix = "my.child")
  public ChildConfig childConfig() {
    return new ChildConfig();
  }

Above configuration is valid and bind to all properties but the spring-boot-configuration-processor cannot render the metadata of the BaseConfig#nest property (nested property on parent class).

Example 2

public class OverrideChildConfig extends BaseConfig {
  private long longValue;
  private final CustomNest nest = new CustomNest();
  @Override
  public CustomNest getNest() { // override getter as return the custom nested object
    return nest;
  }
  // getter and setter ...

  public static class CustomNest extends Nest { // custom class of nested class defined in parent class
    private long longValue;
    // getter and setter ...
  }
}
  @Bean
  @ConfigurationProperties(prefix = "my.override-child")
  public OverrideChildConfig overrideChildConfig() {
    return new OverrideChildConfig();
  }

Above configuration is valid and bind to all properties but the spring-boot-configuration-processor cannot render the metadata of the OverrideChildConfig#nest property.

Executable examples

  • https://github.com/kazuki43zoo/spring-boot-issue-21626

Comment From: kazuki43zoo

I've published the executable example.

Comment From: philwebb

We might be able to refine PropertyDescriptor.isParentTheSame to detect these types. Processing complicated class relationships with the annotation processor is unfortunately quite difficult.

Comment From: kazuki43zoo

@philwebb

Thanks for your quick response !! I found a workaround as follow:

For Example1

public class SpringBootChildConfig extends ChildConfig {
  @ConfigurationProperties("my.child.nest") // mark nested configuration property on sub class
  @Override
  public Nest getNest() {
    return super.getNest();
  }
  @ConfigurationProperties("my.child.child-nest")  // mark nested configuration property on sub class
  @Override
  public ChildNest getChildNest() {
    return super.getChildNest();
  }
}

For Example2

public class SpringBootOverrideChildConfig extends OverrideChildConfig {
  @ConfigurationProperties("my.override-child.nest")  // mark nested configuration property on sub class
  @Override
  public CustomNest getNest() { // override getter as return the custom nested object
    return super.getNest();
  }
}