Spring multiple PropertyPlaceholderConfigurer (in multiple projects) how to override an already defined property? - spring

I have a situation where I need to override properties from one project in another. In project 1, where I have no control over the source or the configuration, there is the following config:
<bean id="propSource1" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:/sample-properties/prop1.properties"/>
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="order" value="-10"/>
</bean>
In another project, which I am working on, I have following config:
<bean id="propSource2" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/sample-properties/prop2.properties</value>
<value>classpath:/sample-properties/prop3.properties</value>
</list>
</property>
<property name="order" value="1000"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
Individually both configurations work fine on their own. The problem happens when I have some property in prop2.properties or prop3.properties that I want to use to override the value for the same property from prop1.properties. It always uses the value in prop1.properties. I have researched quite a bit but did not find anything useful.
Any suggestion is appreciated.

The answer is in #M.Deninum's comment.

Related

Internationalisation with Spring

I have an existing Spring/GWT Application which i need to add internationalisation to. My understanding is that i can use Spring's "ResourceBundleMessageSource" to automatically select the appropriate messages_* file depending on the users location. I tried following this tutorial but i can't seem to get the Application to display my strings in French. As it stands, I've added 2 files messages_en_US.properties and messages_fr_FR.properties into my src/main/resources/i18n folder and added the following to the applicationContext.XML:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<value>classpath:i18n/messages</value>
</property>
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" >
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
</list>
</property>
</bean>
Just wondering 1) if i need additional configuration/glue code and 2) if i can test this easily without having to set the Language/Locale to French on my Redhat Server?
It's likely that your browser sends just "fr" language tag in Accept-Header. Spring is notorious for problems with fall-back, so you may need to copy the messages_fr_FR.properties as messages_fr.properties.
I am sure there must be some ways to configure fall-back, so you want have to use messages_en.properties (try your application with other English locales...), just messages.properties should do, but I am just too lazy/tired to look for solution at the moment.
Here you need to specify below bean in spring.xml.
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
<mvc:interceptors>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
</mvc:interceptors>
This works perfectly fine when you pass lang=es in query string. If still any issue remain.you can check the working example Here .

Heritrix: how to exclude everything but pdf from mirroring?

I found this topic How do i exclude everything but text/html from a heritrix crawl?
I have changed bean to this
<property name="shouldProcessRule">
<bean class="org.archive.modules.deciderules.ContentTypeMatchesRegexDecideRule">
<property name="decision" value="ACCEPT" />
<property name="regex" value="^application/pdf.*"/>
</bean>
</property>
</bean>
But heritrix still saves every file to mirror dir.
I believe you are missing a reject rule above your accept rule. I have the following that works:
<property name="shouldProcessRule">
<bean class="org.archive.modules.deciderules.DecideRuleSequence">
<property name="rules">
<list>
<bean class="org.archive.modules.deciderules.RejectDecideRule">
</bean>
<bean class="org.archive.modules.deciderules.ContentTypeMatchesRegexDecideRule">
<property name="decision" value="ACCEPT" />
<property name="regex" value="^application/pdf.*"/>
</bean>
</list>
</property>
</bean>
</property>
This rejects everything, then accepts everything listed in the following rules.

deployment for different environments with maven and spring

I've got two properties files:
environment.properties:
- project.host.db3.database.name=oracle
application.properties:
- database.name=${project.host.db3.database.name}
The first one represents the environment variables and the second one the properties to be used in a spring project, in this configuration i try to set the environment.properties but of course it doesn't work:
<bean id="systemPropertiesLoader"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}" />
<property name="targetMethod" value="putAll" />
<property name="arguments">
<util:properties location="classpath:environment.properties" />
</property>
</bean>
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="systemPropertiesLoader">
<property name="locations">
<list>
<value>classpath:application.properties</value>
</list>
</property>
<!-- bean using database.name -->
Is it doable?, and if not, how do people have agnostic properties in their projects (like database.name), and only one file (war, jar, etc.) to be deployed?
Well, it seems it's doable for beans xml defined as long as you define your properties it like this:
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="systemPropertiesLoader">
But if you ever try to access the properties from a servlet:
this.getClass().getClassLoader().getResourceAsStream("application.properties");
chances are you get this:
bad port configuration: ${project.host.db3.database.port}
java.lang.NumberFormatException: For input string: "${project.host.db3.database.port}"
In answer to yorkw, now i can have the same war to be deployed in several environments and configure the host with -Denvironment=development, so i can deploy a properties file for development, production, etc. and simply use:
<bean id="systemPropertiesLoader"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}" />
<property name="targetMethod" value="putAll" />
<property name="arguments">
<util:properties location="classpath:**${environment}/**environment.properties" />
</property>
</bean>
Otherwise i should have the application.properties substituted before deployment for every environment. I'm sure there are better solutions than this.

Read property file outside war using spring

enter code hereI have a property file placed in the etc folder. "myapplication.properties" and few other property files in each sub module.. i am try to do the following
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="searchContextAttributes" value="true"/>
<property name="contextOverride" value="true"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>classpath:application.properties</value>
<value>${config}</value>
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
I am trying to do mvn -Dconfig=~/my.properties jetty:run
The properties are read from application.properties but not for config..
While running application i get the ${jdbc.url} not correct .. This url is present in my.properties ..
How can this be achieved ?
Thanks
This is what I had, to run it
<bean id="placeholderConfigConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName">
<value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
</property>
<property name="ignoreUnresolvablePlaceholders">
<value>true</value>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:${config}" />
</bean>
And add -Dconfig=/var//my.properties in the MAVEN_OPTS.. and did mvn jetty:run
Another one line solution I found.. instead of making verbose configuration just do
<context:property-placeholder location="file:${config}"/>
I think this feature becomes available in spring 3.1 via the new Environment abstraction. See the following spring blog for details:
http://blog.springsource.com/2011/02/15/spring-3-1-m1-unified-property-management/.
If spring 3.1 is not an option you can hard-code the filename and path in the spring xml configuration file to some well-known location and then developers can symlink against it.

Loading .properties file in a jar from my web-app

I have created a JAR that I need to use in my WEB-APP. Both are created with spring framework. I would like to load a .properties file outside the JAR file, in the main context of the web-application. And I want to do it with the facilities that Spring offers us.
I've tried to do something like this in my spring.xml file inside the JAR:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>/WEB-INF/classes/my.properties</value>
</property>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="myJob" />
<property name="cronExpression" value="${my.cronExpression}"/>
</bean>
</property>
</bean>
Trying to load my.cronExpression from my.properties file. But without any success.
I always get this error:
Could not resolve placeholder 'my.cronExpression'.
I've tried to change the location with many variants, using classpath:/WEB-INF/classes/my.properties etc...
But I'm not able to load the configuration file.
Thanks for your help.
Use classpath:my.properties - /WEB-INF/classes is root of your classpath.
Try declaring it as follows:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>/WEB-INF/classes/my.properties</value>
</property>
<property name="ignoreUnresolvablePlaceholders">
<value>true</value>
</property>
</bean>
I have gone through your code and want you to try this code snippet
It works well for me :)
<bean id="placeholderProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:/WEB-INF/classes/my.properties" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="order" value="1" />
</bean>

Resources