12

I need to load some properties into a Spring context from a location that I don't know until the program runs.

So I thought that if I had a PropertyPlaceholderConfigurer with no locations it would read in my.location from the system properties and then I could use that location in a context:property-placeholder

Like this

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>    
<context:property-placeholder location="${my.location}"/>

but this doesn't work and nor does location="classpath:${my.location}"

Paul

skaffman
  • 398,947
  • 96
  • 818
  • 769
Paul McKenzie
  • 19,646
  • 25
  • 76
  • 120
  • You won't be able to combine two placeholders like that - they're BeanFactoryPostProcessors, which can't process each other, if you see what I mean. – skaffman Aug 21 '09 at 11:35
  • yes, I figured my problem was something along those lines – Paul McKenzie Aug 21 '09 at 13:00
  • Actually, this smells like an enhancement to PropertyPlaceHolderConfigurer that might be worth filing as a feature request in the Spring JIRA. – skaffman Aug 21 '09 at 14:18

2 Answers2

15

You can do this with a slightly different approach. Here is how we configure it. I load default properties and then overrided them with properties from a configurable location. This works very well for me.

<bean id="propertyPlaceholderConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <property name="locations">
            <list>
                <value>classpath:site/properties/default/placeholder.properties
                </value>
                <value>classpath:site/properties/${env.name}/placeholder.properties
                </value>
            </list>
        </property>
    </bean>
Pablojim
  • 8,542
  • 8
  • 45
  • 69
5

The problem here is that you're trying to configure a property place holder using property placeholder syntax :) It's a bit of a chicken-and-egg situation - spring can't resolve your ${my.location} placeholder until it's configured the property-placeholder.

This isn't satisfactory, but you could bodge it by using more explicit syntax:

<bean class="org.springframework.beans.factory.config.PropertyPlaceHolderConfigurer">
   <property name="location">
      <bean class="java.lang.System" factory-method="getenv">
         <constructor-arg value="my.location"/>
      </bean>
   </property>
</bean>
skaffman
  • 398,947
  • 96
  • 818
  • 769
  • Doesn't work for me using Spring 3.1.3: `org.springframework.beans.NotWritablePropertyException: Invalid property 'location' of bean class [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer]: Bean property 'location' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?` – DeejUK Nov 14 '12 at 12:32