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

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>

Related

Externalise properties working but not overriding existing default value in internal properties

I have a multi module maven project, each module is a jar with its own context file and a set of default properties bundled inside the JAR.
Basically in a core module I have this :
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:core.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
Now i have another module that build the application by loading all relevant XML and adding its own configuration file
<import resource="classpath*:core-context.xml" />
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:application.properties</value>
<value>#{systemEnvironment['foo_bar']}</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
What happen is that all my configurations files are working fine except the one that has default value. I can't override them in application.properties or in the file pointed by the system variable.
I tryed to force the configuration file using the spring.config.location. I do see in the tomcat the message saying that I have the configuration -Dspring.config.file=file:///... (windows path). But spring is totally ignoring it (no message in the logs from Spring).
I tried to switch to PropertySources class without more success.
I'd very like to not have to remove all default properties and put everything in an external file, because lot of parameters are internal to the application and don't have any value for a client.
So what I am missing here ?
Well I finnaly found after many hours so something very ... easy.
Here is the trick : Declare the property placeholder before the import.
When you declare files in a property placeholder, it's the last that win, it seems here it's the exact opposite : the first place holder win.
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:application.properties</value>
<value>#{systemEnvironment['foo_bar']}</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<import resource="classpath*:core-context.xml" />

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.

Load properties file based on language Properties Placeholder

class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath*:app.properties</value>
Loading single properties file works fine, but now I need to load app_en.properties and app_fr.properties file based on the language provided as request(payload) input. How to configure this ?
Use List tag for this
<property name="locations">
<list>
<value>classpath*:app.properties</value>
<value>classpath*:app_en.properties</value>
</list>
</property>

How to call properties file from another properties file using Spring PropertyPlaceholderConfigurer?

I'm working on a command-line Java application using Spring. I have multiple properties files stored in different locations and one properties file containing the path for all those properties. I'm using PropertyPlaceholderConfigurer, to read properties containing the locations of different properties files. I'm not sure of the best way of handling multiple properties.
The application works like this: I will pass the path for first properties file using JVM command -Dmypath=parent.properties. The properties file will look like this:
child1=/location1/child1.properties
child2=/location2/child2.properties
so on
My Parent properties configuration looks like this:
<bean id="parentProperty" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>${mypath}</value>
</list>
</property>
</bean>
The child1 configuration looks:
<bean id="child1Property" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>${child1}</value>
</list>
</property>
</bean>
Now when I call child1 it fails to load the properties.
I have load the parent property file first and then set the particular child1 and child2 variable in system environment variable and load from system environment variable. and its working fine.
code :
<context:property-placeholder location="file:${mypath}/*.properties" ignore-unresolvable="true" />
<bean id="systemPrereqs" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}" />
<property name="targetMethod" value="putAll" />
<property name="arguments">
<!-- The new Properties -->
<util:properties>
<prop key="LOG_LOCATION">${log.location}</prop>
<prop key="child1">${child1}</prop>
</util:properties>
</property>
</bean>
<context:property-placeholder location="file:#{systemProperties['child1']}/*.sql" ignore-unresolvable="true" />
The execution order of BeanFactoryPostProcessors such as PropertyPlaceholderConfigurer can be set by setting the property "order"(see Ordered). By setting the execution priority of parentProperty higher that that of child1Property you can ensure that parentProperty runs first, configuring the value of ${child1}.
It may be easier to load the properties from the classpath, where the locations are included in your classpath, instead of in a file, and then the following will load all your property files.
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="locations">
<list>
<value>classpath*:*.properties</value>
</list>
</property>
</bean>

Specifying Locations relative to the context XML in Spring

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>

Categories