Gary Sedgwick
Gary Sedgwick

Reputation: 383

Strange logic for choosing properties file for spring boot application

I am working on a multi-module Maven project where each module is a spring boot application (i.e. packaged as an executable jar). Some modules have dependencies on others. The project uses platform-bom version 1.1.4.RELEASE.

I've discovered what I believe is strange logic for deciding which application properties files to use - although not explicitly contrary to the information at https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html, it still seems unintuitive at best.

The situation was discovered with the following set of circumstances:

  1. Module A has an application.properties file in its resources folder, so this is packaged into the root of the spring boot jar. This application.properties defines a standard Spring JPA datasource.

  2. Module B depends on A, but has its own application.yml properties file in it (as well as a profile-specific .properties file e.g. application-foo.properties). This file does not have entries for the JPA datasource, but the code does expect a datasource to be injected.

Unexpectedly, it seems that the application.properties from A are read when B's tests run in the Maven build, and used to configure the datasource used by B. From the link above, it could be inferred that this is correct behaviour ("the classpath root" in 24.3 could be taken to mean in the root of a jar on the classpath, which A's jar will be when running tests for B). NB the .yml properties are also processed.

However, if I provide an empty application.properties in B's resources alongside the .yml file, it seems this takes precedence during the tests, and the application.properties from A is no longer processed at all. The .yml file is still processed.

I would have thought from the documentation that all eligible properties files should be processed i.e. if A's application.properties is read, then it still should be if B provides its own file (with B's taking precedence). It also seems that .properties and .yml files are not treated identically (the existence of the application.yml did not stop A's application.properties being read, but having application.properties in B did).

Please could someone clarify what the expected behaviour is, and comment whether the documentation (linked above) is correct? In particular:

1) When the documentation states that properties files can be loaded from "the classpath root", should that include the root of any jars on the classpath too?

2) Should providing an application.properties in B stop A's being found?

3) Should the .yml properties be treated differently in regard to this behaviour?

Upvotes: 0

Views: 718

Answers (1)

M. Deinum
M. Deinum

Reputation: 124516

The classpath root is just a flattened representation of all the files in all the archives it contains. You could consider it like unzipping anything in a directory and then reading it (physically it is different but that is comparable to what happens when reading files). Files closest to you will be read before any other files. Hence when you provide your own application.properties that will override the ones included in jar files.

So yes that will stop the reading of files shipped in jars. Why well imagine 20 jars all containing an application.properties how should an order be guaranteed, which one should win? Especially if they contain overlapping properties. So only one will be read.

.properties and .yml are different files and as such are both read (I even believe .properties are read before .yml files but not sure). So yes that is also expected behavior.

Upvotes: 1

Related Questions