0

Working on a legacy Spring based application (Spring 4.3), I have a strange behavior: environment variables are not resolved by Spring. For example I have this environment variable: HOST_SERVICE_BASE_URL, when I refer to it in the application with ${host.service.base.url} the property is not resolved and the application fails during start up.

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'host.service.base.url' in value "${host.service.base.url} 

I defined these beans for property resolution:

 @Bean public PropertiesFactoryBean applicationProperties( ResourceLoader resourceLoader ) { PropertiesFactoryBean propertiesFactory = new PropertiesFactoryBean(); propertiesFactory.setLocations( resourceLoader.getResource( "/WEB-INF/config/application.properties" ), resourceLoader.getResource( "/WEB-INF/config/application-dev.properties" ) ); return propertiesFactory; } 

And

 <bean id="dataConfigPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="ignoreResourceNotFound" value="true"/> <property name="searchSystemEnvironment" value="true"/> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/> <property name="properties" ref="applicationProperties"/> </bean> 
4
  • Environment variables will never the converted to system properties. Do you really have an environment variable OR do you have a System Property (passed with -D). Also why the mix of XML and Java Config and do you by anychange have multiple PropertyPlaceholderConfigurer instances AND are you loading multiple configs? Commented Aug 13, 2020 at 13:51
  • @M.Deinum I have environnement variables not system properties. The mix with xml is because it's a legacy application and I don't want to migrate all configurations Commented Aug 13, 2020 at 13:56
  • Ah already see your issue. You should be using a PropertySourcesPlaceholderConfigurer not a PropertyPlaceholderConfigurer and loading the properties, unless you need them, should be done using the same class. Commented Aug 13, 2020 at 13:59
  • And yes there are multiple configs loaded Commented Aug 13, 2020 at 14:00

1 Answer 1

2

You are using the (now deprecated) PropertyPlaceholderConfigurer while that can consult the system environment it lacks the feature of mapping those properties to values. I.e HOST_SERVICE_BASE_URL isn't mapped as host.service.base.url.

That support is only available in the SystemEnvironmentPropertySource which is automatically registered and consulted when using the PropertySourcesPlaceholderConfigurer (recommended as of Spring 5.2, but available since 3.1).

<bean id="dataConfigPropertyConfigurer" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> <property name="ignoreResourceNotFound" value="true"/> <property name="properties" ref="applicationProperties"/> </bean> 

Or in Java to replace the applicationProperties bean and XML portion.

@Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); configurer.setLocations({"/WEB-INF/config/application.properties", /WEB-INF/config/application-dev.properties"}); configurer.setIgnoreResourceNotFound(true); return configurer; } 

Or if you really stick with XML use the <context:property-placeholder /> tag, which automatically does this.

<context:property-placeholder properties="applicationProperties" ignore-resource-not-found="true" /> 

or

<context:property-placeholder locations="/WEB-INF/config/application.properties,/WEB-INF/config/application-dev.properties" ignore-resource-not-found="true" /> 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.