Setup
Let's say I have 2 strings files:
Strings_en.properties
Strings_fr.properties
Let's say English is the default language, and all the strings are present, while French lags behind and some strings are missing.
Desired behavior
I want to fall back to English in both of these cases:
- When requesting a completely different locale, such as German.
ResourceBundle.getBundle("path/to/Strings", Locale.GERMAN);
- When requesting a string missing from French.
ResourceBundle.getBundle("path/to/Strings", Locale.FRENCH).getString("only.in.english");
The first fallback is simple enough: as per the documentation, it's enough to have English as the default locale, for example by setting Locale.setDefault(Locale.ENGLISH);
.
Problem
My problem is with the second fallback. If the string is not found in Strings_fr
, the lookup continues to the "parent bundle": getObject() documentation. However, Strings_en
is not the parent of Strings_fr
and a MissingResourceException
is thrown.
Workaround
A simple fix is to rename Strings_en.properties
to Strings.properties
. This makes it the parent bundle for Strings_fr
(and for any other Strings_
, for that matter) and looking up missing strings returns the default English versions.
Problem: the system now has a default localization, but it no longer understands that there is an English localization.
Workaround 2
When fetching a string, check if it's present in the bundle - if not, fetch it from the English one instead.
ResourceBundle bundle = ResourceBundle.getBundle("path/to/Strings", Locale.FRENCH);
if (bundle.containsKey(key)) { return bundle.getString(key); }
return ResourceBundle.getBundle("path/to/Strings", DEFAULT_WHICH_IS_ENGLISH).getString(key);
Problem: this is just a hack, I believe there is an "intended" way to do it.
Question
Is there a simple way to make Strings_en
the parent of Strings_fr
? If not, is it reasonable to for example hardlink Strings_en
to Strings
, so that I can keep English as an explicit localization and at the same time as the default one?
ResourceBundle.getBundle("path/to/Strings", Locale.ENGLISH)
will also give you a bundle based onStrings.properties
– Wysocki*.properties
files to determine the supported languages. So I guess it's just a matter of personal preference: it's the English localization, it shouldn't be hidden under default. – Citarella