Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomcat Context-Params ignored in Spring webapp when using PropertyPlaceholder

Tags:

spring

I was previously using, the now deprecated, class org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer to load a properties file from the server's filesystem. I had the following bean definied:

<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
    <property name="locations" value="${config}"/>
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
    <property name="searchContextAttributes" value="true"/>
    <property name="contextOverride" value="false"/>
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="searchSystemEnvironment" value="false"/>
</bean>

The config is an argument that is passed when starting Tomcat, i.e.

-Dconfig=/path/to/application.properties

For the webapp I also have a context file:

<Context docBase="/path/to/application.war">
    <Parameter name="host" value="localhost" override="false"/>
    <Parameter name="port" value="8080" override="false"/>
</Context>

If the .properties file, specified by the -Dconfig argument, contains the property that some other bean references then the value from the .properties file is used, otherwise the value from the the context xml file is used.

This allowed me to have a set of default properties deployed with the WAR and if required, I was able to specify a .properties file to override particular values.

Now, I'm updating to use the new property abstractions in Spring 3.1 but I can't seem to figure out what the equivalent approach to this is?

I have the same context file and war deployed in the same way, and I now have the following in the application:

<context:property-placeholder
        location="${config}"
        system-properties-mode="OVERRIDE"
        ignore-resource-not-found="true"
        ignore-unresolvable="true"/>

This finds and uses the properties from the properties file, BUT it does not use the values from the context XML file.

How do I get my application to use the context params when using this new property-placeholder?

Thanks.

like image 870
C0deAttack Avatar asked Jul 05 '13 15:07

C0deAttack


1 Answers

To summarise the problem is that the Context Parameters from the servlet context file were not being used to resolve placeholders when using the new Property Placeholder namespace introduced in Spring 3.1.

I have figured out a solution, with the following

<context:property-placeholder location="${config}" local-override="true" ignore-resource-not-found="true"/>

I can specify one or more *.properties files on the local filesystem using a JVM arg, eg:

-Dconfig=/path/app.properties

If a placeholder property cannot be resolved after checking the app.properties file then the Servlet Context Parameters are checked.

This allows me to have default values using context params in a the web.xml and where I need to I can override these values by specifying the location of *.properties files using the config JVM arg.

The key to getting it to work this way was to include local-override="true", which is false by default. I'm not fully sure that it makes sense, since the description for that attribute is:

Specifies whether local properties override properties from files. Default is "false": Properties from files override local defaults.

If the same property key exists in the app.properties and the web.xml the value from the app.properties is used.

like image 153
C0deAttack Avatar answered Sep 30 '22 11:09

C0deAttack