I need to load the i18n localization properties of my Spring web application as a ResourceBundle object in the context of a deployed WAR running on JBoss AS7.
The reason here is that I need to feed in a ResourceBundle object as a parameter to JasperReports to compile reports properly. The parameter "REPORT_RESOURCE_BUNDLE" is used by JasperReports to handle internationalization in the reports with the str() function or the $R{} expression binding. The only accepted type for this parameter is a ResourceBundle object, hence my situation.
I had it working at some point, but it seemed that JBoss was holding onto a stale version of the properties, which I believe was clarified by the fact that it could no longer locate the ResourceBundle using unmodified code after I did a clean, package, and redeploy on the project.
In Spring we have configured a MessageSource Bean as follows, that is able to successfully load and use the properties files as resource bundles:
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource ms = new ReloadableResourceBundleMessageSource();
String[] basenames = {"/WEB-INF/classes/messages/i18n/core_messages",
"/WEB-INF/classes/messages/i18n/mui_messages"};
ms.setBasenames(basenames);
return ms;
}
My current implementation for fetching the ResourceBundle object is as follows:
public ResourceBundle getBeanResourceBundle() {
Locale fromConfig = DEFAULT_LOCALE;
//Resolve Locale from a configuration service
ClassLoader cl = Thread.currentThread().getContextClassLoader();
return ResourceBundle.getBundle("core_messages", fromConfig, cl);
}
It was having issues loading the class using this.getClassLoader() and then started working after I changed to load from the Thread.currentThread(). Yet now the clean:package:deploy has rendered this ineffective and I have reasonable information to suggest to me it stopped actually loading new "core_messages" ResourceBundle objects many deployments back because obvious key-value changes never appeared to change in the deployed application.
The structuring of the deployment is build through maven as follows:
Core module packages as a JAR that is a dependency for the FrontEnd modules that are packaged as WARs for JBoss deployment.
The code that has the services to load things like the ResourceBundle in the method above are in the Core module. The final WAR is one of the FrontEnd modules that is trying to resolve the files from its WEB-INF/classes/.. classpath.
What class loader do I need to access to load from the appropriate classpath?
The MessageSourceResourceBundle class in Spring is an implementation of ResourceBundle that uses the MessageSource to feed its properties. It can be instantiated with a MessageSource object (Autowired) and a Locale. MessageSource already handles what I need in the applications and I just needed to grab a working ResourceBundle which it does as well with Locale.
public ResourceBundle getBeanResourceBundle() {
Locale fromConfig = DEFAULT_LOCALE;
//Resolve Locale from a configuration service
return new MessageSourceResourceBundle(ms, fromNodeConfig); //replace code in my question
}