Bugs in Java 7 Locale or ResourceBundle?
While working on a chapter in an upcoming APress book, I was experimenting with Java 7′s Locale and ResourceBundle classes. Java 7 introduces two new Locale categories: DISPLAY and FORMAT. You can set the default locale for localizable user interface resources independently from the default locale for data Format subclasses. For example, you supposedly can set up a DISPLAY locale to display Spanish (es) resources for the user interface text but use American English (en-US) for date formats.
This does seem to work correctly the first time you load a ResourceBundle, but subsequent calls to getBundle seem to get stuck with previous DISPLAY locale settings. For example, take a look at the following code:
public void setCategoryDefaultLocale(Locale displayLocale, Locale formatLocale) {
Locale.setDefault(Locale.Category.DISPLAY, displayLocale);
Locale.setDefault(Locale.Category.FORMAT, formatLocale);
}
public void demoDefaultLocaleSettings() {
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.SHORT);
ResourceBundle resource = ResourceBundle.getBundle("mypackage.resource.SimpleResources");
String greeting = resource.getString("GOOD_MORNING");
String date = df.format(NOW);
System.out.printf("DISPLAY LOCALE: %s\n",
Locale.getDefault(Locale.Category.DISPLAY));
System.out.printf("FORMAT LOCALE: %s\n",
Locale.getDefault(Locale.Category.FORMAT));
System.out.printf("%s, %s\n\n", greeting, date );
ResourceBundle.clearCache();
}
Now I call the two methods above in succession:
setCategoryDefaultLocale(Locale.forLanguageTag("es-MX"), Locale.US);
demoDefaultLocaleSettings();
setCategoryDefaultLocale(Locale.US, Locale.forLanguageTag("es-MX"));
demoDefaultLocaleSettings();
In the following output, notice that the first call to demoDefaultLocaleSettings does actually grab the es-MX resources for the DISPLAY locale, and it formats the NOW date using the en-US FORMAT locale. That’s exactly what I’d expect. However, the subsequent call (even after flushing the ResourceBundle cache), still loads the es-MX resources despite the explicit request for en-US resources. I expected that ResourceBundle would have loaded and retrieved “Good morning!” after the second call to setCategoryDefaultLocale.
DISPLAY LOCALE: es_MX
FORMAT LOCALE: en_US
¡Buenos días!, 9/18/11 1:59 AM
DISPLAY LOCALE: en_US
FORMAT LOCALE: es_MX
¡Buenos días!, 18/09/11 01:59 AM
I suspect that the real problem isn’t in the Locale.setDefault methods. Instead, I’m going to blame ResourceBundle for this until I can prove otherwise.
If you’ve seen this in the past, let me know. I’m coming up empty for now trying to resolve why I don’t get U.S. English in the second call. Let me know if you know anything about this! Maybe a bug? Maybe user error?

Hi John,
Thank you for your write ups! I am now traveling (actually I am in Irvine, close to you!) so I cannot try it myself, but I believe the ResourceBundle is working correctly. Its getBundle method (without locale instance) loads the resource for the default locale, i.e., Locale.getDefault() value, which won’t be affected by Locale.setDefault(Locale.Category, Locale) invocation.
HTH, Naoto
@naoto
Thanks Naoto, but what is the purpose then of Locale.setDefault(Locale.Category.DISPLAY, aLocale)? My first call to resource bundle does seem to load the es-MX resources:
ResourceBundle resource = ResourceBundle.getBundle(“mypackage.resource.SimpleResources”);
The second call (after I’ve set the default to en-US for DISPLAY), continues to load the es-MX resources. How is the Category.DISPLAY supposed to affect resource bundles?
ResourceBundle is not necessarily related to DISPLAY locale because it’s up to application’s design. Some apps want to load resources that are FORMAT related. So the default behavior just relies on Locale.getDefault().
Having said that, I’d modify your example to ResourceBundle.getBundle(“mypackage…”, Locale.getDefault(Locale.Category.DISPLAY)) as you *already know* that the resource is DISPLAY related.
Locale.setDefault(Category) affects the behavior of the locale sensitive services that explicitly relate to user visible display, such as the locale names for user display, i.e., Locale.getDisplayName().
@naoto
I guess the point of the categories is completely lost on me. I thought the point was to be able to setDefault(category, alocale) and thereafter anything that depended on a default would use the defaults set from the setDefault call. That makes sense to me. But I think you are saying something very different. From the documentation, I interpreted that resource bundles would be related to the DISPLAY locale and Format subclasses would be related to the FORMAT locale. I think I’ve interpreted incorrectly.
Hmm, can you let me know which document made you interpret that resource bundles would be related to the DISPLAY locale?
I had a problem with it.
I’ve been doing a program for jre 1.6 and 1.7. My solution was:
first check the version of jre;
if the Java 6, use
Locale.getDefault (); or
new Locale (System.getProperty (“user.language”)
System.getProperty (“user.country”))
if the Java 7, use
new Locale (System.getProperty (“user.language.format”)
System.getProperty (“user.country.format”))