Specifying Locations relative to the context XML in Spring - java

Is there a way to reference a properties file on a file system (not on a classpath) relative to the Spring's context file itself?
What I want to do is the below:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- I want the below to be relative to this context XML file. -->
<value>app.properties</value>
</list>
</property>
</bean>
I was imagining something like ${contextpath} that I could prepend to the above "app.properties" but couldn't find anything helpful.
Thanks.

You can reference properties on the classpath via the classpath: prefix:
<value>classpath:app.properties</value>

Related

Spring JUnit Test load properties of file outside of src/test/resources

I want to load a properties file into Spring,but Spring cannot find the properties file with this XML.
The File is at /MyProject/MyModule/testData/testProperties.properties
The Test is at /MyProject/MyModule/src/test/MyTest.java
How to make Spring load from the correct path?
<bean id="properties" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="locations">
<list>
<value>testData/testProperties.properties</value>
</list>
</property>
</bean>
You can try using file: prefix
<value>file:/MyProject/MyModule/testData/testProperties.properties</value>

How to load system properties in Spring for properties file location

I am working on a Spring application where the properties file will be packaged inside the the .war file for deployment.
<context:property-placeholder location="classpath:application.properties" />
However, I would like to be able to override them with another file that can be specified in standalone.xml as a system property:
</extensions>
<system-properties>
<property name="CONFIG_FILE_LOCATION" value="/path/to/application.properties"/>
</system-properties>
This was my solution,
<context:property-placeholder location="classpath:application.properties,
file:///${CONFIG_FILE_LOCATION}" />
but apparently Spring is unable to find it
Caused by: java.io.FileNotFoundException: ${CONFIG_FILE_LOCATION} (The system cannot find the file specified)
Does anyone has any idea how I might fix it? Is there another way Spring accesses the system properties?
It is actually possible in Spring to override certain properties by specifying a system property location to another file using this solution:
<context:property-placeholder location="classpath:alarm_notification.properties, file:///${CONFIG_FILE_LOCATION}" />
If a certain property is not overridden inside the file located at CONFIG_FILE_LOCATION, the value from application.properties will be used instead.
Just make sure to have the following configuration in the standalone.bat file used to start the server:
</extensions>
<system-properties>
<property name="CONFIG_FILE_LOCATION" value="/path/to/application.properties"/>
</system-properties>
You need to file namespace for that as follows:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:/myFolder/folder/path/application.properites</value>
</list>
</property>
or as follows:
<context:property-placeholder locations="file:/myFolder/folder/path/application.properites"/>

Spring ignores property file in current directory using that in CLASSPATH instead

I have a Spring properties file defined as:
<bean
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>lanchecker.properties</value>
</list>
</property>
</bean>
According to 23.3 in http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html:
SpringApplication will load properties from application.properties files in the following locations and add them to the Spring Environment:
A /config subdir of the current directory.
The current directory
A classpath /config package
The classpath root
The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).
During development this file resides on the CLASSPATH, at /src/main/resources, and is resolved fine. After packaging I provide another in the current directory but it is ignored and the one from the CLASSPATH still used.
What have I missed here please?
This appears to work:
<bean
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:lanchecker.properties</value>
<value>file:${user.dir}/lanchecker.properties</value> <!-- file values will override classpath if exists -->
</list>
</property>
</bean>
If both exist it will read the resource on the classpath first, then replace the values there with anything in the file.
If neither exist they'll just be a nasty traceback at some later stage when the property values come to be used. There are though some INFO log messages to help solve this. No pleasant, but it's the best I've been able to come up with today

Spring ResourceBundle not found for base name

I'm having problems taking the message values to a properties file.
I'm using intelliJ IDEA and i have a package
com.test.messages
and inside I have the messages.properties file.
Here is my xml
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="com.test.messages.messages"/>
</bean>
When I restart the server this is the WARNING i get
WARNING: ResourceBundle [com.test.messages.messages] not found for MessageSource: Can't find bundle for base name com.test.messages.messages, locale en_US
Any ideas?
Do not keep properties in packages.
Resources directory is a standart place to keep internal properties.
/src/main/resources
or
/src/test/resources
If you want to keep properties separated from the project - use something this kind of spring configuration:
<bean id="props" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
<property name="ignoreResourceNotFound" value="true"/>
<property name="localOverride" value="true"/>
<property name="locations">
<list>
<value>classpath*:messages.properties</value>
<value>file:messages.properties</value>
</list>
</property>
</bean>
So you'd be able to override internal properties with external (don't forget to add the to a classpath using -cp).
Anyway the declaration of the been will look like this:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="${property.name}"/>
</bean>
you should have a file in your project as such:
src\main\resources\com\test\messages.properties
Although I am not IDEA expert, I know that resources such as .property files placed in the source code hierarchy are copied to the classpath when using the IDE alone. However, if you use maven, then it takes over the build and whatever is in the java path is not copied by default. You have to place all your classpath resources in src\main\resources and under whatever hierarchy mirrors the package name to have the same result. So in your case :
src\main\resources\com\test\messages\messages.properties
and maven will copy it properly
I know this is old question, but let me drop my solution :)
Source folder (resources is not package):
/src/main/java/
somepackage/abc.java
/src/main/resources/
messages.properties
Eclipse default output java build path:
myProject/build/classes
Eclipse default deploy path:
WEB-INF/classes
My project's spring context XML file path:
/src/main/webapp/WEB-INF/context.xml
Inject resource bundles,
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="messages"/>
</bean>
As Azee said keeping properties in package is not encourage. In case, messages.properties is in resources package as below:
/src/resources/messages.properties
context.xml should be like:
<property name="basenames" value="resources/messages"/>

External properties file as spring MessageSource not working

Consider below code:
<bean id="busmessageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:bundles/resource</value>
<value>classpath:bundles/override</value>
<value>file:/C:/mmt/override</value>
</list>
</property>
<property name="cacheSeconds" value="100" />
</bean>
Here properties from bundles/resource and bundles/override get fetched when I call busmessageSource.getMessage("anykey", null, null)
but it fails when I try to fetch values for properties in C:/mmt/override
What is correct way of configuring messagesource with external file from the disk.
Also I want file:/C:/mmt/override to override values in classpath:bundles/override if any with the same key exist. How do I override properties from an external file outside of my war folder?
1.) I have these 3 ways:
One solution is to add your "C:/mmt/" folder to your resource classpath.
This is another way that may help you ResourceBundle not found for MessageSource when placed inside a folder
Use this code: (Worked for me)
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename">
<beans:value>file:/path/to/messages</beans:value>
</beans:property>
</beans:bean>
Note1: You must use the } file: prefix and the ReloadableResourceBundleMessageSource class.
Note2: Do not put the ".properties" extension.
2.) You override previous values when you load a new properties file with same property names (keys). You must ensure that you fetch last the properties file you want to use.
You can try
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="defaultEncoding" value="UTF-8"/>
<property name="basenames">
<list>
<value>classpath:bundles/resource</value>
<value>classpath:bundles/override</value>
<value>file:C:/mmt/override</value>
</list>
</property>
</bean>
About message resource keep note:
A plain path will be relative to the current application context.
A "classpath:" URL will be treated as classpath resource.
A "file:" URL will load from an absolute file system path.
Any other URL, such as "http:", is possible too.
I ran into similar question (by the title of your question) and managed to instantiate Spring ResourceBundleMessageSource with java.util.Properties.
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setCommonMessages(properties);
Kind of naive approach, but did the job for my unit testing.

Categories