How to read jBoss configuration files in Spring? - java

I want to have a project independent configuration file that I can access from different projects. What I'm currently trying (and does not give me good results at all):
<bean id="wroProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="${JBOSS_HOME}/standalone/configuration/wro.properties" />
</bean>
I use Spring 3 and JBoss 7.1. My configuration files are under jboss/standalone/configuration/....properties. Besides that I want to read message files from that same directory with:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="messages,local" />
<property name="useCodeAsDefaultMessage" value="true" />
</bean>
Currently it looks for messages.properties and local.properties in src folder?

This is the solution I ended up using, which is platform independent and portable:
<bean id="wroProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="file:#{systemProperties['jboss.home.dir']}/standalone/configuration/wro.properties" />
</bean>
The configuration of the message source is identical.

A ResourceBundleMessageSource uses the basenames provided to (and the locale) to build a resource name (ex. message.properties) which is eventually (in the call stack) used by java.util.ResourceBundle.Control#newBundle(...). This resource name is then looked for on the classpath starting at its root (ex. /message.properties).
If you're on an IDE like Eclipse, your classpath very likely starts at src.
If jboss/standalone/configuration/... is on your classpath as well and the properties file are in there, you can change the basenames to
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="jboss/standalone/configuration/messages,jboss/standalone/configuration/local" />
<property name="useCodeAsDefaultMessage" value="true" />
</bean>

Related

Problems using multiple PropertySourcesPlaceholderConfigurer

Ok, I have been fighting this too long, time to ask for help. HELP!!!
I'm deploying an indipendent jar maven project that will be used as dependency into other projects.
I need that this jar loads its own properties file ("versione.properties" released inside the jar) when the application that will use it, will start up but I want that the application doesn't care about it. This should be in charge on the lib.
I want that who will use this lib, will have just to
include the right dependency inside his pom.xml
add <import resource="classpath*:*-context.xml" /> inside his spring app-context.xml to be sure to include also the lib-context.xml during the spring-context initialization
For this reason, the jar has its own spring lib-context.xml file as the following:
<context:component-scan base-package="it.eng.inps.comppsr" />
<bean id="propertyPlaceholderConfigurer2" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="false" />
<property name="locations">
<list>
<value>classpath:versione.properties</value>
</list>
</property>
</bean>
<bean id="version" class="it.eng.inps.comppsr.util.Versione">
<property name="buildVersion" value="${comppsrutil.build.version}"/>
<property name="buildDate" value="${comppsrutil.build.timestamp}"/>
</bean>
As you can immagine, "versione.properties" file contains comppsrutil.build.version and comppsrutil.build.timestamp.
During my tests, I've tried also <value>classpath*:versione.properties</value>, <value>classpath:/versione.properties</value> and <value>classpath:*/versione.properties</value> but with no luck.
This library is used by a web-service application (a war inside an ear file) and this application has got its own spring app-context.xml that loads it own properties file as described by the following code snippet
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="lookupPropertiesInitializer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="searchSystemEnvironment" value="true" />
<property name="ignoreResourceNotFound" value="false" />
<property name="locations">
<list>
<value>file:///#{lookupPropertiesInitializer.pathToProperties}</value>
<value>classpath*:version.properties</value>
</list>
</property>
</bean>
<context:component-scan base-package="it.eng.inps.util, it.eng.inps.comppsr" />
<import resource="classpath*:*-context.xml" />
When I start the application (it runs inside JBoss EAP 7.3), I get this error:
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'comppsrutil.build.version' in value "${comppsrutil.build.version}"
So, it seems that something goes wrong within the lib initialization.
If I rename the "versione.properties" file in "version.properties" (so with the same name used by the app properties file), this error desappear, I think, because it is loaded by the application PropertyPlaceholderConfigurer, so the lib property file is well located.
For this reason I think that the bean propertyPlaceholderConfigurer2 defined inside lib-context.xml, doesn't work as I expected but I didn't understand why.
Does anyone give me any tips?

Springboot war project with tomcat and external application properties?

How can we provide an external application.properties, datasource.properties file with war project that runs on external tomcat? Is there any way to provide these files path as vm arguments in tomcat configuration. Also is it possible to get the values from these files as #Value annotation if use the above configuration?
Have a PropertySourcesPlaceholderConfigurer
<bean name="propertySourcesPlaceholderConfigurer" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="location" value="file:${conf.dir}/app.properties" />
</bean>
where conf.dir you can pass it through JVM arguments like -Dconf.dir=yourconfigFilePath
and use like the following
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${dataSource.driverClassName}" />
<property name="url" value="${dataSource.url}" />
...
File app.properties
dataSource.driverClassName=org.apache.derby.jdbc.ClientDriver
dataSource.url=jdbc:derby://localhost:1527/dbpath

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" />

Spring UTF-8 message resource from external jar issue

I have a problem with UTF-8 message sources in Spring MVC application. I've tried two implementations of AbstractMessageSource: ResourceBundleMessageSource and ReloadableResourceBundleMessageSource. I have an external jar with i18n messages contained in com.mypackage.i18n package
The configuration for ResourceBundleMessageSource:
<bean id="propertiesMessageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="com.mypackage.i18n.messages" />
<property name="useCodeAsDefaultMessage" value="true" />
</bean>
This configuration loads finds and loads properties, but fails with UTF-8, because this implementation just doesn't support UTF-8.
The configuration for ReloadableResourceBundleMessageSource:
<bean id="propertiesMessageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="com.mypackage.i18n.messages" />
<property name="useCodeAsDefaultMessage" value="true" />
<property name="fileEncodings" value="UTF-8" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
This configuration doesn't find properties. I know that this implementation to have reloadable resources needs properties to be located somewhere in WEB-INF directory and it doesn't restrict resources to be located somewhere else if you don't need reloading of resources.
According to the class java:
Note that the base names set as "basenames" property are treated in a slightly different fashion than the "basenames" property of ResourceBundleMessageSource. It follows the basic ResourceBundle rule of not specifying file extension or language codes, but can refer to any Spring resource location (instead of being restricted to classpath resources). With a "classpath:" prefix, resources can still be loaded from the classpath, but "cacheSeconds" values other than "-1" (caching forever) will not work in this case.
Can someone advice me how to solve the problem: I need to use another approach or somehow modify config of ReloadableResourceBundleMessageSource to find resources from jar?
I've found a solution. Proper ReloadableResourceBundleMessageSource configuration looks like this:
<bean id="propertiesMessageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:com/mypackage/i18n/messages" />
<property name="useCodeAsDefaultMessage" value="false" />
<property name="fileEncodings" value="UTF-8" />
<property name="defaultEncoding" value="UTF-8" />
<property name="cacheSeconds" value="-1"/>
</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.....

Categories