Can't load multiple property files in spring's application context - java

I have three property files placed in a resource folder in classpath. The problem i am facing is while i am able to load invidual files separately i am unable to load them when they are declared together.
Please see the XML below:
<bean name="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="resources\label"/>
</bean>
This is working but the XML given below isn't:
<bean name="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames" value="resources\label,resources\button,resources\messages"/>
<property name="cacheSeconds" value="1"/>
</bean>
I wish to declared them together as I wish to use a single bean to access all three files. Help required!

Found the answer . It should be like this `
<property name="basenames">
<list>
<value>classpath:resources\label</value>
<value>classpath:resources\button</value>
<value>classpath:resources\messages</value>
</list>
</property>
</bean>

Do it like this
<property name="basenames">
<list>
<value>resources\label</value>
<value>resources\button</value>
<value>resources\messages</value>
</list>
</property>

Related

How can I use environment variable in hibernate config file?

I am currently using database parameters in hibernate(Version 4.0.1) file through properties file.
I want to use some database parameters from environment variable. How can I fetch values from java files and set in to xml files before that loads in context.
<bean id="propertyConfigurer"
class="org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer">
<constructor-arg ref="configurationEncryptor" />
<property name="locations">
<list>
<value>classpath:/test/demo/prop/DataParam.properties</value>
</list>
</property>
</bean>
<bean id="data" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass">
<value>${driverClass}</value>
</property>
<property name="jdbcUrl">
<value>${dbconnecturl}</value>
</property>
.
.
.
</beans>
I got some idea to make an object of Configuration class but I don't know where to write that code and how it would be implemented.
You need to use spring expression language to configure the properties from OS environemnt variables as shown below:
<bean id="propertyConfigurer"
class="org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer">
<constructor-arg ref="configurationEncryptor" />
<property name="locations">
<list>
<value>classpath:/test/demo/prop/DataParam.properties</value>
</list>
</property>
</bean>
<bean id="data" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass">
<value>#{ systemProperties['driverClass']}</value>
</property>
<property name="jdbcUrl">
<value>#{ systemProperties['dbconnecturl']}</value>
</property>
.
.
.
</beans>
You can use as <property name="username" value="#{systemProperties['dbUsername']}"/> for instance.
The variable systemProperties is predefined, you can see Xml Based Configuration for more details.

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>

Java, Spring setting up themes confusing and not working

spring-servlet.xml setting up theme beans:
<bean id="themeSource"
class="org.springframework.ui.context.support.ResourceBundleThemeSource">
<property name="basenamePrefix" value="theme-" /> // also tried WEB-INF.resources.theme- and WEB-INF/resources/theme- here, same problem
</bean>
<bean id="themeChangeInterceptor"
class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
<property name="paramName" value="theme" />
</bean>
<bean id="themeResolver"
class="org.springframework.web.servlet.theme.CookieThemeResolver">
<property name="defaultThemeName" value="default" />
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
<ref bean="themeChangeInterceptor" />
</list>
</property>
</bean>
under WEB-INF/resources, where are 3 theme files:
theme-black.properties
theme-blue.properties
theme-default.properties
each file contain this accordingly:
css=themes/black.css
css=themes/blue.css
css=themes/default.css
i have folder WEB-INF/themes , which contains 3 of these css files, i think the content of css isn't important here.
now error i run into is :
javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Theme 'default': No message found under code 'css' for locale 'en'.
so basically it just can't find the css value for themes, which means it can't find the properties file...
what I am doing wrong? feel free to ask questions
You should try to put theme properties into classpath (as is written in docs). Classpath is not /WEB-INF folder. See this question for clarity.
By default the delegate will be a
org.springframework.ui.context.support.ResourceBundleThemeSource that
loads properties files from the root of the classpath.
If you do don't want to put the theme.properties file under "classes" folder, you can put it under "META-INF" folder. If you use maven to create and manage the project, the "META-INF" folder is also unser the class path.
For example, if you put the themes under "META-INF/theme", you can do the following stuff to make it works.
<!-- resolves localized <theme_name>.properties files in the classpath to allow for theme support -->
<bean class="org.springframework.ui.context.support.ResourceBundleThemeSource" id="themeSource">
<property name="basenamePrefix" value="META-INF.theme."/>
</bean>
here the problem is not with css file actually ResourcebundleThemeSource trying to find theme-default.properties file in rot of classpath .ie. under the src folder. so put your all properties file under thier, and i am sure your problem will resolve.
Are you trying to use the i18N features in your application , regarding the localization if yes, then you need to add the below code
<"bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages" />
<property name="cacheSeconds" value="3000" />
</bean>
Otherwise remove your code <ref bean="localeChangeInterceptor" /> from the below code
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
<ref bean="themeChangeInterceptor" />
</list>
</property>
</bean>
I hope this code will work properly.....

How to reuse Spring XML fragments

I am working on Spring based application. The XML is simple but contains several almost identical fragments. For example I have 5 different DAO objects, 2 queues etc. Configuration of each DAO looks like:
<bean id="deviceDaoTarget" class="com.mycompany.dao.hibernate.DeviceDAOHibernateImpl"
autowire="byName" />
<bean id="deviceDAO" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.mycompany.dao.DeviceDAO</value>
</property>
<property name="interceptorNames">
<list>
<value>hibernateInterceptor</value>
<value>deviceDaoTarget</value>
</list>
</property>
</bean>
I'd be happy to use some kind of import with parameters. For example I'd like to create parametrized configuration of DAO like this:
<bean id="${dao.target}" class="${dao.class}"
autowire="byName" />
<bean id="deviceDAO" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>${dao.interface}</value>
</property>
<property name="interceptorNames">
<list>
<value>hibernateInterceptor</value>
<value>${dao.target}</value>
</list>
</property>
</bean>
and then call it several times with different parameters, e.g.:
<import resource="spring-dao.xml">
<param name="dao.interface">com.mycompany.dao.hibernate.DeviceDAO</param>
<param name="dao.class">com.mycompany.dao.hibernate.DeviceDAOHibernateImpl</param>
<param name="dao.target">deviceDaoTarget</param>
</import>
Is something like this possible?
You can define a <bean id="parentBean" abstract="true" ...>...</bean> with the common configuration and then have <bean id="childBean" parent="parentBean" ...>...</bean> with just specific configuration for that bean.

property-placeholder location from another property

I need to load some properties into a Spring context from a location that I don't know until the program runs.
So I thought that if I had a PropertyPlaceholderConfigurer with no locations it would read in my.location from the system properties and then I could use that location in a context:property-placeholder
Like this
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
<context:property-placeholder location="${my.location}"/>
but this doesn't work and nor does location="classpath:${my.location}"
Paul
You can do this with a slightly different approach. Here is how we configure it. I load default properties and then overrided them with properties from a configurable location. This works very well for me.
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="locations">
<list>
<value>classpath:site/properties/default/placeholder.properties
</value>
<value>classpath:site/properties/${env.name}/placeholder.properties
</value>
</list>
</property>
</bean>
The problem here is that you're trying to configure a property place holder using property placeholder syntax :) It's a bit of a chicken-and-egg situation - spring can't resolve your ${my.location} placeholder until it's configured the property-placeholder.
This isn't satisfactory, but you could bodge it by using more explicit syntax:
<bean class="org.springframework.beans.factory.config.PropertyPlaceHolderConfigurer">
<property name="location">
<bean class="java.lang.System" factory-method="getenv">
<constructor-arg value="my.location"/>
</bean>
</property>
</bean>

Categories