I'm having difficulty trying to override a property declared in a profile-specific application properties file on the classpath with another value declared in an overrides file on the file system.
I have an auto-configured Spring-boot application (that is, using @EnableAutoconfiguration
) that has multiple profiles, which I launch using PropertiesLauncher
rather than JarLauncher
(the reason having to do with deployment constraints - I need to deploy an exploded directory rather than an archive into a read-only filesystem.)
Within the root of my application, I have some profile-specific application properties, for example:
application-dev.properties
application-qa.properties
application-prd.properties
And let's say, for the sake of argument that application-dev.properties
contains:
foo.bar=baz
foo.baz=other
For any environment, it may be necessary to override an existing property, as well as supply an absent one (like a production password, for example), and the issue I'm seeing is with overriding properties already declared in an application-${profile}.properties
file on the classpath. (Supplying properties not present in the classpath file works fine, this is not the issue.)
Say I have an overrides properties file in a file system location such as:
/local/appname/dev/overrides/application.properties
and I want to override the property, foo.bar
, as well as declare a new property, foo.password
.
Therefore the contents of the overrides file are:
foo.bar=overridden-value
foo.password=something
When I launch the application, I use a command line something like this:
java -Dspring.config.location=file:/local/appname/dev/overrides/
-Dspring.profiles.active=dev
org.springframework.boot.loader.PropertiesLauncher
--debug &
The issue I am seeing is that although foo.password
, the property not declared in the application-dev.properties
file is picked up, the override of foo.bar
is ignored - I still see the value, baz
from application-dev.properties
rather than the value, overridden-value
from /local/appname/dev/overrides/application.properties
.
With the --debug
option enabled, I can see the ConfigFileApplicationListener
logging that it has loaded both the overrides file (from the filesystem) and the profile-specific file (from the classpath), in that order.
I'm tempted into the perhaps naïve conclusion that because the overrides file is listed first, it is being loaded first then overridden by the 'default' profile-specific file from the classpath, which is listed later. I do appreciate however, that order of listing in the log doesn't necessarily correlate with behaviour. And I have tried varying the order of paths declared on the spring.config.location
property, so that classpath:
is listed before file:...
but this hasn't helped and I't not convinced it would anyway, given that the Spring-boot documentation clearly states that the default properties locations are always searched even if you supply a value for spring.config.location
.
The Spring-boot documentation is very specific about the order that properties are resolved for a Spring-boot executable JAR, in descending order of precedence:
System.getProperties()
).java:comp/env
RandomValuePropertySource
that only has properties in random.*
.application.properties
including YAML and profile variants).application.properties
including YAML and profile variants).@PropertySource
annotations on your @Configuration
classes.SpringApplication.setDefaultProperties
).Take note of lines 6 and 7 - properties outside over properties inside your jar.
What's not stated, as far as I can see, and which may be the source of my confusion/issue, is what happens when you're not using a JAR but an exploded directory (and therefore PropertiesLauncher
.)
If the behaviour of an exploded directory were consistent with what's stated for a JAR, I'd expect that the values of properties declared in /local/appname/dev/overrides/application.properties
would override any of the same name declared in classpath:application-dev.properties
, but this doesn't seem to be the case.
Also noted from the Spring-boot documentation (appendix C.4 on PropertiesLauncher
) is mention of the loader.home
property, which is described as '... [the] Location of additional properties file, e.g. /opt/app
(defaults to ${user.dir}
)'.
So I tried using loader.home
instead of spring.config.location
, but to no avail.
(Update: I also tried using loader.config.location
and I have two notes: it seems to want a file rather than a directory (so its behaviour is not analogous with spring.config.location
), and when I did supply a file path rather than the parent directory, it still didn't help.)
Can anyone spot what I'm doing wrong, or what incorrect assumption(s) I'm making?
Spring Boot will automatically load the properties in an application. properties file for all profiles, and the ones in profile-specific . properties files only for the specified profile. In this way, we can easily provide different configurations for different environments.
active properties to activate or include profiles from an application.
run(SpringBootTestApplication. class, args); and used SpringApplicationBuilder class to add properties to the app. Now, these properties are defined in the program, You can apply condition and change property values based on your requirements. Save this answer.
Spring boot provides command line configuration called spring.config.name using that we can change the name of application. properties. Here properties file name will be my-config.
Thanks, Dave, your suggestion was 100% correct.
If I rename the properties file in /local/appname/dev/overrides
to application-dev.properties
then the property values from that file do override the ones in classpath:application-dev.properties
.
I was sure I had tried this combination yesterday, but I think what must have stopped it working was when I was playing around with specifying the spring.config.location
and got that wrong so it wasn't looking for the override file in the right place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With