Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

property not found with multiple context:property-placeholder

I am using spring 3.1 with spring profiles to load the beans. In my app context file, I load the properties like :

<context:property-placeholder order="1"  location="classpath*:META-INF/spring/*_${spring.profiles.active}.properties" ignore-unresolvable="true"/>

And then I use the property value to load the data source bean like

<property name="driverClassName" value="${database.driverClassName}"/>

It works fine. The problem starts when I add a couple of more property placeholders so that properties from some database tables can be loaded.

This uses a properties reference loaded by

<bean id="configFactoryBean"
class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
   <constructor-arg ref="globalSystemConfiguration"/>
</bean>

To add to the details, this configFactoryBean uses the datasource to load the properties from the database.

When I do this, I have the following exception:

java.lang.ClassNotFoundException: ${database.driverClassName}

My analysis is that its trying to load the datasource before resolving the property from the first context property placeholder. I may be wrong. Or maybe spring profile variable is not resolved properly.

Can anyone please help me to fix this.

Thanks Akki

like image 806
Abby Avatar asked Jun 03 '13 08:06

Abby


4 Answers

This bug about multiple property placeholders might relate to your problem: https://jira.spring.io/browse/SPR-9989

When using multiple PropertyPlaceholderConfigurer in conjunction with @Value annotation and default value for placeholders syntax (ie ${key:defaultValue}), only the first PropertyPlaceholderConfigurer is used. If this configurer does not contain the desired value, it falls back to @Value default even if the second PropertyPlaceholderConfigurer contains the value.

Affects Version/s: 3.1.3

like image 80
user3415190 Avatar answered Oct 11 '22 13:10

user3415190


Each <context:property-placeholder> creates a new instance of PropertyPlaceholderConfigurer - it gets messy easily. You should have one such thing per application and on application level, not on libraries' one - that makes maintenance much easier.

For more details and a suggestion how to cope with it look here: http://rostislav-matl.blogspot.cz/2013/06/resolving-properties-with-spring.html

like image 36
Rostislav Matl Avatar answered Oct 11 '22 11:10

Rostislav Matl


In my application I am using property-placeholder configurer in following way and it works very well. You can try that.

<bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
          <property name="locations">
            <list>
                <value>classpath*:META-INF/spring/*_${spring.profiles.active}.properties</value>
            </list>
          </property>
    </bean>

I think this should resolve your problem. :)

like image 45
Japan Trivedi Avatar answered Oct 11 '22 13:10

Japan Trivedi


Since you have suggested hardcoding the path to the configuration file works, try using the profiles attribute on the tag to selectively include the configuration.

<beans profile="profileName">
    <context:property-placeholder  order="1"  location="classpath*:META-INF/spring/hardcoded.properties" ignore-unresolvable="true"/>
</beans>

<beans profile="profileName2">    
    <context:property-placeholder order="1"  location="classpath*:META-INF/spring/hardcoded.properties" ignore-unresolvable="true"/>
</beans>

See this article explaining profiles: http://java.dzone.com/articles/using-spring-profiles-xml

like image 30
Kevin Bowersox Avatar answered Oct 11 '22 12:10

Kevin Bowersox