Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring property placeholder not working

I've read similar issues on the stackoverflow.com, but none of the solutions helped me. The following configuration I use (maven project structure): the src/main/resources/properties/app.properties file

#possible values: dev test prod
mode: dev

In the Spring configuration:

<context:property-placeholder location="classpath:properties/app.properties"/>
<import resource="classpath:/spring/db/${mode}-datasource-config.xml"/>

Based on the value of ${mode} I want to import the corresponding datasource configuration file.

When I run the embedded tomcat7 using the mvn clean install tomcat7:run command I'm getting the error:

10, 2013 5:52:29 PM org.apache.catalina.core.StandardContext loadOnStartup
SEVERE: Servlet /SpringWebFlow threw load() exception
java.lang.IllegalArgumentException: Could not resolve placeholder 'mode' in string value "classpath:/spring/db/${mode}-datasource-config.xml"

The target/classes/properties/app.properties file exists.

I'm using IntelliJ IDEA and in the editor I can click on the "${mode}" in <import resource="classpath:/spring/db/${mode}-datasource-config.xml"/> and see its value in the property file. Also the editor itself change ${mode} onto the grey colored dev showing it can recognize the property value. In the editor I see: <import resource="classpath:/spring/db/dev-datasource-config.xml"/>

Any ideas why I'm getting the error and how it can be resolved?

like image 675
Alexandr Avatar asked May 10 '13 11:05

Alexandr


2 Answers

Property placeholders in imports are resolved against enviroment variables or system properties only.

Since version 3.1 you can use an ApplicationContextInitializer to add PropertySources to the Enviroment that will solve your problem.

see http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/

Other option to do the same is using profiles: http://blog.springsource.org/2011/02/14/spring-3-1-m1-introducing-profile/

Edit

For example:

Add the initializer to web.xml

<context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>foo.bar.AppContextInitializer</param-value>
</context-param>

And the initializer:

public class AppContextInitializer implements ApplicationContextInitializer<ConfigurableWebApplicationContext> {

        @Override
        public void initialize(ConfigurableWebApplicationContext applicationContext) {
            Properties props;
            try {
                props = PropertiesLoaderUtils.loadAllProperties("/some/path");
                PropertiesPropertySource ps = new PropertiesPropertySource("profile", props);
                applicationContext.getEnvironment().getPropertySources().addFirst(ps);
            } catch (IOException e) {
                // handle error
            }
        }
    } 
like image 76
Jose Luis Martin Avatar answered Oct 02 '22 10:10

Jose Luis Martin


Is this properties file format valid? I think you should use following contents for app.properties:

#possible values: dev test prod
mode=dev
like image 34
hoaz Avatar answered Oct 02 '22 10:10

hoaz