Spring - Set properties before load resources in applicationContext - java

in my applicationContext.xml I have a list of spring cfg files.
<import resource="classpath:resource1.xml"/>
<import resource="classpath:META-INF/resource1.xml"/>
<import resource="classpath:META-INF/resource1.xml"/>
<import resource="classpath:resource1.xml"/>
<import resource="classpath:resource1.xml"/>
And these files need some properties that are setted.
When I'm set these properties in JVM every runs OK.
But when load by properties file in my applicationContext, I receive an exception because the app couldn't "translate" the property key(${key}) in value.
<bean id="propSource" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="-999"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="location">
<value>classpath:/application.properties</value>
</property>
</bean>
I think that spring load import xml files before to load properties file.
How I can solve this?
Thnks

Related

How I can configure properties file right?

I have maven project with several modules
this is part of database-config.xml in office-core module:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:application.properties</value>
</list>
</property>
</bean>
I have application.properties files on several places:
c:\projects\office\app\office-core\application.properties
c:\projects\office\app\office-core\src\main\profiles\application.properties
c:\projects\office\app\application.properties
In my opinion with this config in database-config.xml I should can use the properties file in my database-config.xml
but I cant... Any help ?
You should put the application.properties file to src/main/resources directory to have it effectively on classpath. Then it should work.
I think it will not work because those paths are not part of your classpath. I suggest you to have some default configuration and to have configuration override per module, something like that:
<bean id="overrideConfigurer" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
<property name="location" value="file:/SomeFolderInFileSystem/conf.properties"/>
<property name="ignoreResourceNotFound" value="true"/>
</bean>

how to use values from external property files in spring xml configuration?

I tryed to pull password from hibernate config to separate properies file.
Initially I had this config:
...
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
...
<property name="username" value=root />
...
After I wrote following
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db.properties</value>
</list>
</property>
</bean>
...
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
...
<property name="username" value="${db.username}" />
...
in db.properties I wrote following:
username=root
I got following trace:
org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: class path resource [db.properties] cannot be opened because it does not exist
file with configurationa and db.properties locates in same folder.
You can ignore the classpath: keyword and just use db.properties in the list.
it working after:
put db.properties to src/main/resources
replace this configuration
${db.username}
with
${username}

Spring: Loading PropertyPlaceholderConfigurer

Here is the situation:
The xml configuration looks as follows:
<bean id="ppConfig1"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:c:\test\env.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
</bean>
<bean id="string" class="java.lang.String" depends-on="ppConfig1">
<constructor-arg value="${env.app.type}"/>
</bean>
<bean id="ppConfig2"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="string">
<property name="locations">
<list>
<value>file:c:\test\#{string}.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="false" />
</bean>
As is evident, I want load a specific property file (e.g. app1.properties) based on the value of key env.app.type in C:\test\env.properties.
The code to load/test the above config looks as follows:
ApplicationContext context = new ClassPathXmlApplicationContext(
"SpringBeans.xml");
String ss = (String)context.getBean("string");
System.out.println(ss);
This seems not working. It failing with following error:
Exception in thread "main"
org.springframework.beans.factory.BeanInitializationException: Could
not load properties; nested exception is
java.io.FileNotFoundException: C:\test\${env.app.type}.properties (The
system cannot find the file specified) at
org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:87)
The file c:\test\env.properties looks as follows
env.app.type=app1
One interesting observation is that when I comment out the ppConfig2, everything works fine and correct value of env.app.type is printed. I am open to any other suggestion to get around this. My basic requirement is to select the property file at run time based on the property specified in env.properties. (I am using spring 3.1.0)
You need something like this:
<context:component-scan base-package="com.foo.bar" />
<context:property-placeholder location="file:c:/test/${env.app.type}.properties" />
<bean id="service" class="com.foo.bar.ExampleService">
<property name="foo" value="${foo}" />
</bean>
package com.foo.bar;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
#Configuration
#PropertySource("file:c:/test/env.properties")
public class SpringConfig{
}
And "foo" value comes from app1.properties file. Basically, one file is being loaded with #PropertySource, the other with the regular property placeholder.
I think you are trying to do things that Spring does not like. The normal order for bean initialization is :
fully construct bean post processors
construct other beans
init other beans
As long as those 3 passes are cleanly separated, all will be ok, but you have a post processor bean (ppConfig2) depending on a simple bean (string).
IMHO, you should avoid such construct if possible. Even if it works now, you are under the risk of problem arising at any modification of you application context because you are allready on the edge.
Could it be acceptable to use environment variables or system properties to avoid that a bean post-processor depends on another bean post-processor ? If yes, you would'nt be bothered by ppConfig1 and simply have :
<bean id="ppConfig2"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="string">
<property name="locations">
<list>
<value>file:c:\test\${configured_env}.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="false" />
</bean>
If environment variables or system properties are not an option, you could use programmatic configuration as suggested by Andrei Stefan.
You can do this with util:properties:
<util:properties id="envProperties" location="env.properties"/>
<util:properties id="properties" location="#{envProperties.getProperty('env.app.type')}.properties"/>
<context:property-placeholder properties-ref="envProperties" ignore-unresolvable="true" ignore-resource-not-found="true"/>
<context:property-placeholder properties-ref="properties" ignore-unresolvable="true"/>
BTW there's a bug in Spring that prevents Spring EL from being evaluated inside location attribute in context:property-placeholder.

override property value ${abc.xyz} in bean property in spring configuration file

I have beans xml file, which loads multiple property files for creating its beans. All these property files are under a root folder like root/abc/abc.properties , root/xyz/some.properties etc..
<bean id="x".....
....
<util:properties id="properties" location="${config.base.dir}/abc/abc.properties" />
......
</bean>
<bean id="y".....
....
<util:properties id="properties" location="${config.base.dir}/xyz/some.properties" />
......
</bean>
I want to override put the value of config.base.dir somewhere in top so that I can keep changing the root location, should this be possible by defining some property on top?
If using Maven, you can have a version of abc.properties in the test/resources/abc/ folder. this will be picked up on the classpath before the main/resources/abc/abc.properties file.
Does this help?
Why do you want to ' keep changing the root location' ?
system properties overrides...
<!-- Configuration property files -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName">
<value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
</property>
<property name="locations">
<list>
<value>classpath*:config.properties</value>
</list>
</property>
</bean>

Spring 3.0 Could not load properties

Im the getting the following Error/exception when deploying web app:
org.springframework.beans.factory.BeanInitializationException: Could
not load properties; nested exception is
java.io.FileNotFoundException: Could not open ServletContext resource
[/WEB-INF/WebAppProps]
Below is the context tag that Im using in applicationContext.xml to point to WebAppsProps.properties file
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:/WEB-INF/WebAppProps.properties" />
I have also used:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/WebAppProps.properties" />
The file is actualy in the filesystem & below is the snapshot of my project structure:
I also tried , putting "WebAppProps.properties" on the classpath and used these 2 variations
variation 1:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:WebAppProps.properties</value>
</property>
</bean>
variation 2:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>WebAppProps.properties</value>
</property>
</bean>
Please see below:
However Im still getting same error/exception.
Please Advise
Thank you
Same issue i crossed,
Fix:
Solution
your bean like below:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>/WEB-INF/database.properties</value>
</property>
</bean>
create folder properties under WEB-INF it look like WEB-INF/properties/database.properties
because the class PropertyPlaceholderConfigurer default search properties folder first under /WEB-INF/ so it concatenate your file name as path
I think that you should change your code and put the properties like that :
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/jdbc.properties" />
</bean>
Spring 4 this is how I would configure the properties file
#Configuration
#PropertySources({
#PropertySource("classpath:application.properties"),
#PropertySource(value = "${application.properties}", ignoreResourceNotFound = false)
})
public class WebServiceConfig {
---
}
And when starting my tomcat in setenv.sh I define the path as
-Dapplication.properties=file:location-of-file/application.properties"
Notice file: prefix here. That is important.
Now you can drop file anywhere on your file system and change the path without ever changing the code
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>WebAppProps.properties</value>
</property>
</bean>
Just put the file on the classpath in the root of the classes directory.
you have 2 options:
if you dont need to get the bean, but only the properties:
<context:property-placeholder location="/WEB-INF/WebAppProps.properties" file-encoding="UTF-8"/>
or if you need the bean (it may happens you want to inject your properties bean, if you need to read many props...)
<bean id="configProperty" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>/WEB-INF/config.properties</value>
<value>/WEB-INF/setup.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true"/>
</bean>

Categories

Resources