14

I have three resource files in class path:

labels.properties:

language = Default

labels_en.properties:

language = English

labels_fr.properties:

language = French

Is there a way to get a ResourceBundle object that always loads labels.properties NO MATTER what my default Locale is?

ResourceBundle.getBundle("labels") returns the one corresponding to the current default locale (as expected).

The only way I can find is to set the default locale to a non-existing locale, but this may break other modules.

Thank you!

Locale.setDefault( Locale.ENGLISH);
Assert.assertEquals( "English", ResourceBundle.getBundle( "labels").getString( "language"));
Locale.setDefault( Locale.FRENCH);
Assert.assertEquals( "French", ResourceBundle.getBundle( "labels").getString( "language"));
Assert.assertEquals( "French", ResourceBundle.getBundle( "labels", new Locale( "do-not-exist")).getString( "language"));
Locale.setDefault( new Locale( "do-not-exist"));
Assert.assertEquals( "Default", ResourceBundle.getBundle( "labels").getString( "language"));
  • You might need to call `ResourceBundle.clearCache()` before trying: `ResourceBundle.getBundle( "labels", new Locale( "do-not-exist")).getString( "language"));`. (From [this question](http://stackoverflow.com/questions/10981521/dynamically-change-resourcebundle-locale-in-java?rq=1)). – Duncan Jones Jun 19 '14 at 11:41
  • 1
    @Duncan Thank you for your comment. It didn't work, though. If `new Locale("do-not-exist")` (I should have named it "does-not-exist"...) is not found, `ResourceBundle` tries to load one with `Locale.getDefault()` instead, not the default version of the bundle. –  Jun 19 '14 at 11:53

1 Answers1

17

You can pass in a ResourceBundle.Control which, regardless of requested Locale, always searches only the root ResourceBundle:

ResourceBundle rootOnly = ResourceBundle.getBundle("labels",
    new ResourceBundle.Control() {
        @Override
        public List<Locale> getCandidateLocales(String name,
                                                Locale locale) {
            return Collections.singletonList(Locale.ROOT);
        }
    });
VGR
  • 40,506
  • 4
  • 48
  • 63
  • 1
    Thank you! It works! I didn't know the existence of `Locale.ROOT`, I thought `new Locale("")` were not allowed... By the way, isn't your code equivalent to `ResourceBundle.getBundle("labels", Locale.ROOT)`? Are there other reasons to extends `Control` (for this specific problem)? Following test case passes: `Locale.setDefault( Locale.ENGLISH); Assert.assertEquals( "Default", ResourceBundle.getBundle( "labels", Locale.ROOT).getString( "language"));` –  Jun 22 '14 at 15:19
  • 1. Yes, passing Locale.ROOT to every call to ResourceBundle.getBundle will accomplish the same thing. 2. There are many other reasons to use ResourceBundle.Control, such as controlling the caching of bundles and controlling whether to only search for .properties resources and/or subclasses of ResourceBundle. The javadoc (to which I linked) lists all the behaviors you can override. – VGR Jun 22 '14 at 20:49
  • Agree with @VGR, if you go through the `java.util.ResourceBundle` class, invoke `ResourceBundle.getBundle("baseName", Locale.ROOT);` will do the same thing but skip the step to try to get bundle with `Locale.getDefault()`, which is redundant in this case. – qtopierw May 10 '18 at 05:36