XML Resourcebundles and how to make I18N refactoring safe

Java Resourcebundles are cumbersome. Without good IDE support, you are lost. It is hard to maintain the different property files, keep them in sync and take care of correct character encoding. And even if you manage all this, you still have the resource keys hard coded in your source code. It is very hard to detect where your resource keys are used.

But fortunately you don’t have to live with these limitations! So instead storing different property files for each resource key, just keep them together in one simple XML file? Instead of using hard coded String constants in your source code, just use a generated Java constant interface to access the bundle?

mogwai.sourceforge.net provides a simple I18N framework to help you with this task. Given the following XML definition:

<?xml version="1.0"?>
	<Bundle interface="de.mogwai.common.client.binding.BindingBundle">
			<Text lang="de">Pflichtfeld nicht ausgefüllt</Text>
			<Text lang="en">Missing required field</Text>
			<Text lang="de">Wert ist länger als {0} Zeichen</Text>
			<Text lang="en">Value is longer than {0} characters</Text>

and the following Maven POM addition:

                    <taskdef name="XMLResourceBundle"
                    <XMLResourceBundle src="src/main/java" dest="src/main/resources" defaultLanguage="en"
                                       encoding="ISO8859_1" javaEncoding="ISO8859_1">
                        <fileset dir="src/main/resources">
                            <include name="*.xml"/>

Will generate the property files for you. It will also generate nice constant interfaces like this one to access the resource keys:

public interface BindingBundle {

	String BUNDLE_NAME = "de/mogwai/common/client/binding/BindingBundle";

The resource bundles can be accessed the following way:

// Create a ResourceHelper to access the bundles by Bundle name
private static final ResourceHelper BINDINGHELPER =

// Get a localized value from the bundle
String theCurrentTypeName = helper.getText(ERDesignerBundle.CURRENTDATATYPE);
comments powered by Disqus