Not able to find messages with ResourceBundleMessageSource - java

I am currently using the following code which is working correctly:
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>/WEB-INF/resources/lang/lang</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
When I change ReloadableResourceBundleMessageSource to just ResourceBundleMessageSource it stops working.
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/resources/lang/lang" />
</bean>
I keep getting exceptions saying "No message found under code 'title' for locale 'en_US'." (title is an example)
After reading similar questions, I have also tried changing the value of basename parameter to any of the following, without success:
WEB-INF/resources/lang/lang
.WEB-INF.resources.lang.lang
WEB-INF.resources.lang.lang
resources.lang.lang
lang.lang
lang
classpath:resources.lang.lang
Making a file called lang_en_US.properties didn't help either.

Apparently, it is looking in the java folder (root of classpath) and not the web folder.
I created a new package called lang in the java folder and moved the lang*.properties files to it.
Then I put lang.lang as the value for basename and it started to work.
UPDATE: This stopped working after a project clean. The lang files should go into the "resources" folder, not the java folder. They technically end up in the same place after a build, but the IDE seems to ignore non-class files in the java folder and simply skips them.

Related

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.

How to read jBoss configuration files in Spring?

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>

How to automatically reload messages.properties files in Java/Spring?

I've been working on an interntaional website using Java/Spring using #springMessage() tags and message.properties files. See my recent question: In Java/Spring, how to gracefully handle missing translation values?
I want to be able to edit (overwrite) the messages.properties files and be able to see the new translations immedatiately in my browser (without restarting Tomcat).
I thought that http://commons.apache.org/proper/commons-configuration/userguide/howto_filebased.html#Automatic_Reloading would be what I need, but I'm not sure how to edit my webmvc-config.xml to use that.
Figured it out. It worked after I edited webmvc-config.xml:
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename">
<value>${content.path.config}/WEB-INF/messages</value>
</property>
<property name="defaultEncoding" value="UTF-8" />
<property name="cacheSeconds" value="2"/>
</bean>
(I just needed to add the cacheSeconds property.)

Modify Spring message text without restarting application?

I am doing a Spring web application. I use Spring 3.1 and Eclipse. I run the application via Jetty within Eclipse.
I have many JSP pages that contain text such as this:
<spring:message code="label.subject"/>
This type of text comes from a file called messages_en.properties defined in Spring context:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
</bean>
I need to constantly modify the text in messages_en.properties. However, new text does not show up in the application without restarting Jetty, which is quite inconvenient to me.
How can I modify Spring message text without restarting Jetty?
Thanks for your help!
Regards.
The answer is in ResourceBundleMessageSource's documentation itself: use ReloadableResourceBundleMessageSource.
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
<property name="cacheSeconds" value="1"/>
</bean>
You can do it in many ways. You can monitor your files for change with a file monitor and reload the resource programmatically. You can take a look at this: http://docs.oracle.com/javase/tutorial/essential/io/notification.html
Basically the idea would be upon starting your app to register a file monitor on your resource and then when you change it, just reinitialize your resource.

Categories