Java 11.02 Spring Boot 2.3.3.RELEASE

I am having problem with application.properties file.

application.properties sometimes doesn't gets parsed when using Configuration List POJO. It seams to be some type of race condition. Not all the elements of list are parsed. The more fields I have in POJO the most likely it fail to parse application.properties. Most of the fields are String datatype in POJO

POJO:

public class ExternalRdbConfig {

    private String name;
    private int expirationInSeconds;
    private String driver;
    private String url;
    private String user;
    private String password;

        public ExternalRdbConfig(){}

        // getters, setters...
}

Configuration:

@Configuration
@EnableAutoConfiguration
@ConfigurationProperties(prefix = "external.resource")
public class ExternalConfig {
        private final ArrayList<ExternalRdbConfig> rdb;

         public ExternalConfig() {
        this.rdb = new ArrayList<>();
         }

        public List<ExternalRdbConfig> getRdb() {
        return rdb;
     }

         dump() {
         .......
         }
}

Controller

@RestController
public class EdpController {

    @Autowired
    private ExternalConfig externalConfig;

    // Start only after all beans are loaded
    @EventListener(ApplicationReadyEvent.class)
    private void start() throws Exception {
        externalConfig.dump();
    }
}

application.properties

external.resource.rdb[0].name=Name0
external.resource.rdb[0].expirationInSeconds=0
external.resource.rdb[0].driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
external.resource.rdb[0].url=jdbc:sqlserver://10.102.130.197:1433;DatabaseName=R
external.resource.rdb[0].user=sa

external.resource.rdb[1].name=Name1
external.resource.rdb[1].expirationInSeconds=1
external.resource.rdb[1].driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
external.resource.rdb[1].url=jdbc:sqlserver://10.102.130.197:1433;DatabaseName=R
external.resource.rdb[1].user=sa

external.resource.rdb[2].name=Name2
external.resource.rdb[2].expirationInSeconds=2
external.resource.rdb[2].driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
external.resource.rdb[2].url=jdbc:sqlserver://10.102.130.197:1433;DatabaseName=R
external.resource.rdb[2].user=sa

external.resource.rdb[3].name=Name3
external.resource.rdb[3].expirationInSeconds=3
external.resource.rdb[3].driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
external.resource.rdb[3].url=jdbc:sqlserver://10.102.130.197:1433;DatabaseName=R
external.resource.rdb[3].user=sa


external.resource.rdb[4].name=Name4
external.resource.rdb[4].expirationInSeconds=4
external.resource.rdb[4].driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
external.resource.rdb[4].url=jdbc:sqlserver://10.102.130.197:1433;DatabaseName=R
external.resource.rdb[4].user=sa

Comment From: DMarkD

I can also reproduce with Spring Boot 2.2.5.RELEASE

Comment From: philwebb

It's hard to say exactly what's going on, but having a @ConfigurationProperties class also be a @Configuration class is a little unusual. I'd recommend not doing that and keeping them as regular @Component beans.

If that doesn't fix it, please could you provide a small sample application that we can run so that we can debug the problem.

Comment From: DMarkD

edp2.zip

Changing to @Component did not help. I attached file with project. I am currently using Eclipse Version: 2019-03 (4.11.0). The project is stripped and simplified.

Basically I have 3 different external.resource definitions (jdbc, http, file). Each of this resources is a List[POJO]. When I run the program I only get external.resource.file[xx] parsed. If I remove external.resource.file[xx] from application.properties, then once in a while jdbc[xx] and/or http[xx] gets parsed.

Does Spring Boot support multiple List[POJO] in the same @ConfigurationProperties->prefix?

Comment From: jnizet

I've been able to reproduce the issue with your code. But reading it, I immediately suspected issues caused by the naming of several of your methods.

For example, you have a method named boolean isFile() in ExternalResourceConfig, which clashes (in terms of Java Bean properties) with the method List<ExternalFileConfig> getFile(). If you rename these isXxx() methods to, for example, hasXxx(), so that Spring doesn't think they're getters for boolean properties, then everything is populated correctly.

Comment From: philwebb

Thanks @jnizet, that is indeed the problem. The combination of String<List> get... and boolean is... confuses the binder into sometimes trying to bind a list, and sometimes a boolean.

We had a similar issue in the past with setters (see #16206).

I'm going to make this one an enhancement to see if we can provide a better error.

Comment From: DMarkD

By changing to boolean hasXxx() fixed the problem.

Comment From: snicoll

@DMarkD, we'd like to enhance the error message as Phil indicated above, please don't close the issue.

Comment From: philwebb

I've tweaked the logic so that a get/is combo favors the get. This aligns well with the existing logic we added for #16206.