Below is the part of spring-context.xml where PropertyPlaceholderConfigurer bean is defined:
<bean id="propertyResource" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:property-files/config-info.properties</value>
<value>classpath:property-files/biservices-config.properties</value>
<value>classpath:dao-config.properties</value>
<value>classpath:environmentLocator.properties</value>
</list>
</property>
</bean>
However, after putting a breakpoint # PropertyPlaceholderConfigurer#setLocations I didn't find all the property files being passed to the setter method.
Please note that the file environmentLocator.properties and dao-config.properties are present in different jar files, although they are on the classpath.
What could be the issue?
Related
i added following in my applicationContext File
<bean id="properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:stage.properties</value>
<value>classpath:environment.properties</value>
</list>
</property>
</bean>
where i need to access stage.properties file values .stage.properties file is in src/main/resources
i have written following line in my java class to access this file
#Value("${spring.username}")
private String usr;
but i am getting valu for usr is like =${spring.username}
what i am missing here?
#Value("${spring.username}") notation requires the use of PropertyPalceholderConfigurer / PropertySourcesPlaceholderConfigurer depending on Spring version to resolve property placeholder. Either
Solution 1
Replace
<bean id="properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:stage.properties</value>
<value>classpath:environment.properties</value>
</list>
</property>
</bean>
with
<context:property-placeholder location="classpath:stage.propertes,classpath:environment.properties"/>
Make sure to import the Spring context namespace
Solution 2.
Use SpEL to access your properties bean with #Value as follows
#Value("#{properties['spring.username']}
private String usr;
This will access the spring.username property of the properties bean in your context
I want to know how to access to a properties file that is under share from a java class (under alfresco) which will be exported later as a .jar file under alfresco/lib.
As reported in this Alfresco forum post you should register a Spring bean in your context exploiting the PropertyPlaceholderConfigurer, setting the proper location of you properties file will be found.
<bean id="custom-properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders">
<value>true</value>
</property>
<property name="locations">
<list>
<value>classpath:alfresco/extension/custom.properties</value>
</list>
</property>
</bean>
From now on every time you define a bean you can use placeholders taken from the property file, which has a common key=value format.
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.
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>
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>