I'm trying to use PropertiesFactoryBean to load all files ending with .propfrom certain directory.
<bean id="props" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="file:/etc/app/*.prop"/>
</bean>
When running this as Junit test, everyting works OK and org.springframework.core.io.support.PropertiesLoaderSupport#loadProperties get list of all files (wildcard expanded) as FileSystemResource
and loads them.
However when running in OSGI environment (Karaf) PropertiesLoaderSupport#loadProperties will get single OsgiBundleResource with path set to /etc/app/*.prop which is invalid, of course.
Try to use the locations property instead of location (which supports only one resource)
<bean id="props" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations" value="file:/etc/app/*.prop"/>
</bean>
Related
I have developed a webapplication which is having jsp and java code. Right now I have placed all the key-value into a env/lifecycle specific properties file (like conf-dev.properties,conf-stg.properties,conf-prod.properties).
I want to externalize these properties file so that it can be placed outside of war(without effecting the war).
right now war file is tightly coupled with properties file. if i have to modify any thing i have to build and make war and deploy.
I have very limited access on deployment server machine (only have access for one folder where i can put my configuration files) & deployment process is handled by CI(jenkin & automated script).
I explored on internet and came to know that we can achieve this using spring, would like to know what is the best way to achieve this?
As you are using Spring I suppose you already use PropertyPlaceholderConfigurer. If not you should ;)
The location of a property file can be anything that can be resolved as spring Resource. This includes classpath, servletcontext and also file references as URIs (file:///... For absolute paths)
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="${config.file.location}" />
</bean>
If I understand your question, then you can use Class.getResourceAsStream(String) the linked Javadoc says (in part)
This method delegates to this object's class loader. If this object was loaded by the bootstrap class loader, the method delegates to ClassLoader.getSystemResourceAsStream(java.lang.String).
The better way to externalize env specific properties is to use "user.home" or "user.dir".
Thanks #Martin F..
Resolved:This is the final one i used and its working fine in dev,stage Env.
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="false"/>
<property name="order" value="1"/>
<property name="locations">
<list>
<value>classpath:conf-${cisco.life}.properties</value>
<value>file:///${openshift.home}/data/conf-${cisco.life}.properties</value>
<value>file:${openshift.home}/data/conf-${cisco.life}.properties</value>
</list>
</property>
</bean>.
and i used script action hook in openshift to set the lifecycle on system level.
appname=echo $OPENSHIFT_APP_NAME
case "$appname" in
*dev)export JAVA_OPTS_EXT="${JAVA_OPTS_EXT} -Dcisco.life=dev";
echo "setting up env life dev for " $appname
;;
*stage)export JAVA_OPTS_EXT="${JAVA_OPTS_EXT} -Dcisco.life=stg;
echo "setting up env life as stg for " $appname.
I have property place holder in my spring context.xml file
<bean id="propertyConfigurer" class="com.techpleiad.poc.RMCPropertyUtil">
<property name="basenames" value="file:${config.file.dir}/prop_application" />
<property name="defaultEncoding" value="UTF-8" />
<property name="cacheSeconds" value="30"></property>
</bean>
and this property 'config.file.dir' is not getting resolved.
'config.file.dir' is the environment variable and when i debug the code and check for the basename the file path comes as it is.. '{config.file.dir}/prop_application'
I need to know what spring code/classes are involved in resolving such properties.
How i could debug and resolve this problem?
You'll need to register a PropertySourcesPlaceholderConfigurer with a reference to your property sources (or not since this is an environment property which are implicitly added).
With XML you can do that with
<context:property-placeholder location="classpath:spring.properties" />
With Java config, simply define a static #Bean annotated method which returns a PropertySourcesPlaceholderConfigurer.
You can try with Spring SpEL to get the system properties
#{systemProperties['config.file.dir']}
To read environment variable use
#{systemEnvironment['config.file.dir']}
The systemEnvironment property contains all the environment variables on the machine where the program is running. Meanwhile, the systemProperties contains all the properties that we set in Java when the application started, using the -D argument.
I'm currently working on a project involving Apache Tiles, but ran into the following problem. The project folder has (a or multiple) white space(s) in the path name.
C:\Users\MyUsername\Documents\Dropbox\Subfolder\My Projects\GymApp
Now, to my surprise, when I use Apache Tiles it tries to load the tile-definition.xml from the following location:
C:\Users\MyUsername\Documents\Dropbox\Subfolder\My%20Projects\GymApp\src\main\webapp\WEB-INF\configurations\tile-definition.xml
So the problem lies in the part where tool X tries to convert all white spaces to %20 (URL encoding), where tool X being: Windows, Java, Tomcat, Spring or Apache Tiles. Because of this Apache Tiles cannot load the file, since the file does not exist (if I try to open the URL in Windows explorer it gives me the error that the file does not exist, same thing shows up in the console log of my IDE).
As for my question, is it possible to have an Apache Tiles project running in a folder which contains white spaces? If so, how is this done?
Note*: If I change the folder name of My Projects to My_Projects the project runs without any errors, so I know that the folder path is at fault here.
-- Edit --
I use this code to configure the tilesConfigurer
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
</bean>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions" value="/WEB-INF/configurations/tiles.xml" />
</bean>
-- Edit 2 --
This is what my IDE log shows:
DEBUG BaseLocaleUrlDefinitionDAO:154 - File Resource file:/C:/Users/MyUsername/Documents/Dropbox/Subfolder/My%20Projects/GymApp/src/main/webapp/WEB-INF/configurations/tiles.xml at file:/C:/Users/MyUsername/Documents/Dropbox/Subfolder/My%20Projects/GymApp/src/main/webapp/WEB-INF/configurations/tiles.xml not found, continue
DEBUG BaseLocaleUrlDefinitionDAO:154 - File Resource file:/C:/Users/MyUsername/Documents/Dropbox/Subfolder/My%20Projects/GymApp/src/main/webapp/WEB-INF/configurations/tiles_en.xml at file:/C:/Users/MyUsername/Documents/Dropbox/Subfolder/My%20Projects/GymApp/src/main/webapp/WEB-INF/configurations/tiles_en.xml not found, continue
DEBUG TestDispatcherServlet:938 - Could not complete request
javax.servlet.ServletException: Could not resolve view with name 'home' in servlet with name ''
Do you use context-relative paths when specifying your tilesConfigurer bean? Because if you do that, it shouldn't matter if your project folder contains spaces.
I have the following code in my dispatcher-servlet.xml:
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
</bean>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles/config/template-definitions.xml</value>
<value>/WEB-INF/tiles/config/page-definitions.xml</value>
</list>
</property>
</bean>
...and even if my project folder contains a space, Tiles still finds the definition-xml.
I know that this is an old thread but it wasn't marked as solved and I had a similar problem and maybe this will help other people.
With the Tomcat parallel deploy when you add ##2 to specify the war version, that will be expanded into a folder with the same(including the # chars) and those are escaped to %23 which had the same result - tiles.xml couldn't be loaded.
To solve this I override the URLApplicationResource class, and in both constructors instead of
file = new File(url.getPath());
I used
file = new File(url.toURI());
I'm using Spring in a Console java application. I'm using PropertyPlaceholderConfigurer to load database details, and it works flawlessly:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:/appdata/configs/myapplication/connection.properties" />
</bean>
So the root dir will be relative to where the jar is located. I need the same functionality with log4j.properties
log4j.appender.file.File=/appdata/configs/myapplication/myapplication-log.log
How can I achieve this without defining environment variables?
Just tried it like this:
log4j.appender.file.File=\\appdata\\configs\\myapplication\\myapplication-log.log
And it works fine.
I need to pass a folder (java.io.File) as a function parameter.
I tried to just declare the location of the folder, but it looks in SERVER_HOME (/home/user/tomcat).
So my next try is to inject a File (directory) which is located in WEB-INF/myFolder.
my first try failed:
<bean name="path" class="java.io.File">
<constructor-arg value="classpath:WEB-INF/myFolder" />
</bean>
But it looks for /home/user/tomcat/classpath:WEB-INF/myFolder
I've been messing around but I can't figure out how to do it.
Any help or advice would be great.
Thank you all!
You are not supposed to access the file system from a webapp, especially not to make assumptions about the webapps own file representation. WEB-INF/myfolder may or may not be a directory, depending if you are dealing with a WAR (no) or an exploded WAR (yes). If you absolutely need a file system resource, try to acquire it using System.getPreference("java.io.tmpdir").
OK, here are a few hints:
Use a Factory bean to retrieve the File. Let it
Create a temporary directory
Extract the contents of the jar to that temporary directory
return the temporary directory in it's getObject() method
Then inject the factory bean into your bean:
<!-- This is a Factorybean that creates a file -->
<bean class="com.yourcompany.ConfigFolderCreator" id="configDir">
<property name="packageToUnpack" value="com.yourcompany.yourpackage" />
</bean>
<bean class="com.your.legacy.Api">
<!-- inject the factory bean instead of a file -->
<property name="configFolder" ref="configDir" />
</bean>
You could use spring's FileSystemResource class
<bean id="bean" class="org.springframework.core.io.FileSystemResource">
<constructor-arg><value>your.file</value></constructor-arg>
</bean>