How to get the default ResourceBundle regardless of current default Locale
Asked Answered
M

1

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"));
Martino answered 19/6, 2014 at 11:29 Comment(2)
You might need to call ResourceBundle.clearCache() before trying: ResourceBundle.getBundle( "labels", new Locale( "do-not-exist")).getString( "language"));. (From this question).Handyman
@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.Martino
V
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);
        }
    });
Vrablik answered 20/6, 2014 at 11:5 Comment(3)
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"));Martino
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.Vrablik
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.Naphthol

© 2022 - 2024 — McMap. All rights reserved.