Is there any way for a Spring Boot web application to abort at startup if a required property is not set anywhere (neither in the application.properties file nor the other property sources)? Right now, if the property is included in another property, it seem that Spring Boot simply avoids substitution.
For example, in my application.properties file, I have the line:
quartz.datasource.url=jdbc:hsqldb:${my.home}/database/my-jobstore
Right now, if "my.home" is not set elsewhere, Spring Boot is setting the url literally to "jdbc:hsqldb:${my.home}/database/my-jobstore" (no substitution).
I would like to have the application fail to start if the property my.home
were not set anywhere else.
Although they work, I think the approach in the foremost answer is somewhat brittle, as it only works for the predefined name(s), and will silently stop checking the when someone changes
quartz.datasource.url
in the configs to use a different expansion.Ideally, I want this value of
ignoreUnresolvablePlaceholders
to befalse
to get wholesale expansion checking when parsing my configs such asapplication.properties
or its YAML variants, but it's hard-coded totrue
for these cases. This unfortunately leaves strings such as${FOO}
in its unexpanded form ifFOO
cannot be found, making troubleshooting extremely painful. This is especially the case for fields that don't readily appear in the logs such as passwords.While I couldn't find a way of changing
ignoreUnresolvablePlaceholders
short of modifying Spring Boot's classes, I did find an alternative of using a customPropertySource
implementation and defining a new syntax such as "${!FOO}
" to indicateFOO
must exist as an environment variable or die. (The OP didn't mention whethermy.home
is an environment variable but the code below is for environment variables.)First, an
EnvironmentPostProcessor
implementation is required for registering the customPropertySource
. ThisStrictSystemEnvironmentProcessor.java
does this as well as holds the implementation of the customPropertySource
:Instead of returning
null
, an exception is thrown for names that start with!
.This
META-INF/spring.factories
is also required so that Spring initializes ourEnvironmentPostProcessor
:Then henceforth, I can write all environment variables substitutions in my configs as
${!FOO}
to get strict existance checking.The default behaviour in current versions of Spring Boot (1.5.x, 2.0.x, 2.1.x) is to throw an exception if a placeholder can not be resolved.
There will a be an exception like this one :
It works because a bean of type
PropertySourcesPlaceholderConfigurer
(from spring-context) is automatically registered in Spring Boot, in this class :PropertyPlaceholderAutoConfiguration
. And by default, the propertyignoreUnresolvablePlaceholders
inPropertySourcesPlaceholderConfigurer
is set to false, which means an exception must be thrown if a placeholder is unresolved (be it nested or not).Create a bean with a simple
@Value(${my.home})
annotated field. - Then Spring will try to inject that value and will fail and therefore stop when the value is not there.Just
@Value(${my.home}) private String myHomeValue;
is enough for normal (not Boot) Spring applications for sure! But I do not know whether Boot has some other configuration to handle missing values: If there is an other failure management than you could check that value in an PostCreation method.To throw a friendly exceptions just put a default null value in property, check and throw a exception in afterProperty method.