jump to navigation

Why change something that ain’t broken? August 29, 2006

Posted by globalizer in Java, Locales.
trackback

I have often wondered how and why it was decided to include the default locale in “the middle” of the Java ResourceBundle fallback tree. A quick search of the Sun and Java documentation and reference sites shows that it is very difficult to find any traces of the previous implementation, however, so I probably shouldn’t expect to ever find out.

In fact, the only documentation I can find right now is the hardcopy version of The Java Class Libraries, Second Ed., Volume 1, that I have sitting on my office bookshelf. In this book, Patrick Chan, Rosanna Lee and Douglas Kramer describe the lookup mechanism:

If a class with the class name cannot be loaded or instantiated, the class name then is successively shortened until a resource bundle class is successfully loaded and instantiated. The shortening process goes like this. First, the complete class name – base name plus the desired locale identifier – is used. If this fails, the locale identifier is continually shortened by removing the rightmost underscore and subsequent characters until a resource bundle class is successfully located and instantiated. If this fails, the process starts again using the locale identifier of the default locale (see Locale.getDefault()).

This sounds like an eminently sensible lookup order to me. On a system with the default locale of ja_JP, and the following properties files:

MyResources.properties
MyResources_ja.properties
MyResources_ja_JP.properties
MyResources_es.properties
MyResources_es_ES.properties

a lookup for MyResources with a locale of ‘en_US’ will go through the following fallback chain (ignoring for now the class vs. properties files question):

MyResources_en_US
MyResources_en
MyResources
MyResources_ja_JP
MyResources_ja

We don’t have any resources with an English locale identifier (‘en_US’ or ‘en’), but since we actually have a base version of the resource bundle, the lookup will stop there, and not get to the ‘ja_JP’ and ‘ja’ versions – these bundles belonging to the default locale will only come into play if, for some unfathomable reason, we did not include the base version. The base version can of course be in any language, but we can at least control what that language is.

This however, is not how the fallback mechanism currently works. As described in the JDK 6 APIs, the default locale is now included in the middle of the tree, before the base resource bundle. So, in the example above, a user looking for English strings will instead go through the following fallback:

MyResources_en_US
MyResources_en
MyResources_ja_JP
MyResources_ja
MyResources

Since we do in fact have a ‘ja_JP’ resource, the fallback will stop there, and Japanese will be provided in this case.

I just have a very hard time understanding why this behavior will ever be desirable, while I have plenty of real life examples where it is extremely undesirable. For instance:

A global company creates an application which will be used worldwide, but for performance reasons it will be physically deployed in 3 different geographical locations (the Americas, Europe/Middle East/Africa, Asia Pacific). The company provides translations into a total of 10 languages, with English being used as the default for everybody else. And for maintenance reasons, English is only provided in the base version of the resource bundles (no _en versions).

So, we have 3 local operations teams installing the application in their environments, and in 2 of them the systems happen to be set up with English as the system locale, but in the 3rd, the one located in Japan, the default locale is Japanese. Since the only AP translations provided are Simplified Chinese, Traditional Chinese, Korean and Japanese, people in Australia, New Zealand, Indonesia, etc. all get served Japanese. Probably not the best recipe for success.

Of course, some of this can be remedied by providing an ‘_en’ resource, since people looking for an ‘en’ locale would then actually see English. It would do nothing to help any other locale combinations, however. Only a change of the system default locale would make the system work as designed.

Comments»

1. globalizer - August 30, 2006

Oracle seems to agree with my dim view of the current locale fallback benavior. In their Globalization Development Kit their OraResourceBundle class implements a fallback mechanism which does not consider the default locale:
http://www.stanford.edu/dept/itss/docs/oracle/10g/appdev.101/b10971/oracle/i18n/util/OraResourceBundle.html

2. OK, so it WAS broken, and SHOULD have been fixed… « Musings on software globalization - November 7, 2008

[…] have been fixed… November 7, 2008 Posted by globalizer in Java, Locales. trackback Here I complained about a seemingly wrongheaded change in the Java locale look-up algorithm. It turns […]


Leave a comment