Codementor Events

ResourceBundle Class In Java

Published Mar 08, 2025
ResourceBundle Class In Java

1. Introduction

Locale-sensitive applications must retrieve locale-specific resources(messages, labels, colors, images, etc.) at runtime. In Java, the abstract class java.util.ResourceBundle is a convenient and efficient way to achieve that. It loads locale-specific resources, such as text messages, labels, and configurations, from external properties or class files. In this article, you will learn how to effectively use the ResourceBundle class in your Java code.

2. Definition

A resource bundle is a set of key-value pairs associated with a specific locale. In Java, there are two types of resource bundles:

  • Property-based(.properties files): This is the most common type.
  • Class-based(ex: ListResourceBundle): Use this type if you want to handle resources that are not strings.

This tutorial only covers property-based resource bundles.

3. Creating a Resource Bundle

A property resource bundle file is a property file in which each line is a key-value pair defining the property.

  greeting = Hello

Resource bundles are organized into families. All resources in a single-family share the same base name. The file naming structure is as follows:

baseName_languageCode_CountryCode
baseName_LanguageCode

The use of underscore is mandatory. Also, the language and country codes follow the locale semantics as explained in this article on Locales.
The best practice is to start by creating a default file for cases where no specific file fits. Then create a specific file for each locale used in the application.
Below are examples of resource bundle files belonging to the same family messages.

# File: messages.properties
greeting = Hello!

# File: messages_en.properties
greeting = Hello!

# File: messages_fr.properties
greeting = Salut!

# File: messages_es.properties
greeting = ¡Hola!

4. Loading a Resource Bundle

4.1. Loading a Resource Bundle

Once you have created the different resource files for your application, you can access the resources in a specific resource file using the following static methods from the java.util.ResourceBundle class.

  • static ResourceBundle getBundle(String baseName): Returns the resource bundle with the given baseName associated with the default Locale.
  • static ResourceBundle getBundle(String baseName, Locale locale): Same as the previous method, but use the Locale argument instead of the default Locale.

In case many resource files are eligible, the methods will chain the resulting resource bundles from the very specific to the more general one.

baseName_LanguageCode_CountryCode -> baseName_LanguageCode -> baseName

The following code shows how to load a resource bundle in Java:

     //First way: without a locale
        ResourceBundle propertiesWithDefaultLocale = ResourceBundle.getBundle("messages");//Search for messages.properties
        //Second way: with a specific locale
        Locale locale = Locale.FRENCH;
        ResourceBundle properties = ResourceBundle.getBundle("messages",locale);//Search for messages_fr.properties

Important: Because the bundles are loaded by the classloader, You should provide the bundle names as fully qualified class names. This means, you should include the package name if applicable.

4.2. Retrieving a property from a Resource Bundle

After obtaining the ResourceBundle object, you can retrieve a specific value in the file using the following methods:

  • Object getObject(String key): Returns an object for the given key.
  • String getString(String key): Returns a string value for the given key. This is the appropriate method when working with property-based resource bundles.

Below is an example of retrieving the properties from the messages resource bundle:

        ResourceBundle properties = ResourceBundle.getBundle("messages");//Uses the default Locale
        String greeting = properties.getString("greeting");
        String gratitude = properties.getString("gratitude");
        String farewell = properties.getString("farewell");
        System.out.println("Greeting : "+greeting);
        System.out.println("Gratitude : "+gratitude);
        System.out.println("Farewell : "+farewell);

5. Locating a Locale-specific Resource

We said earlier that the getBundle(String baseName, Locale givenLocale) method call will chain all the eligible resource bundles in case there are many candidates. The first resource bundle that can be instantiated in the candidate list is called the result bundle. Below is the process Java follows to find the result resource bundle:

5.1. Generate the list of candidate bundles

Based on the arguments of the getBundle(String baseName, Locale givenLocale) method, Java will generate this as possible resource bundle names:

  • baseName_givenLocaleLanguageCode
  • baseName_givenLocaleLanguageCode_givenLocalCountryCode

To illustrate that, if the base name is messages and the given locale is fr_FR, then the following candidate bundle names will be generated:

  • messages_fr_FR
  • messages_fr

5.2. Find the result bundle that can be instantiated in the candidate list

Java will then iterate over the list of candidate bundles to find the first one that can be instantiated. This typically means that Java can read the file and retrieve its content. If none is applicable, it moves to the next step.

5.3. Find the result bundle using the default Locale

In case no resource bundle can be instantiated using the given locale(non-existing file for example), Java will try to use the default locale. This means, it will try to instantiate the following bundles:

  • baseName_defaultLocaleLanguageCode
  • baseName_defaultLocaleLanguageCode_defaultLocalCountryCode

5.4. Find the result bundle using the base name

If the previous step still fails to find a suitable resource bundle, Java will attempt to instantiate the bundle using only the base name.

5.5. Throw MissingResourceException

At last, a MissingResourceException is thrown to indicate that no resource bundle could be instantiated using the given parameters.

6. Constructing the Parent Chain of a Resource

After obtaining the result resource bundle, Java will build the parent chain of that particular resource bundle. The parent chain is made of all candidate bundles that are below the result bundle in the candidate list. Only resources that can be instantiated are part of the parent chain. The default resource bundle(with the base name) is always the last in the parent chain.

Let us an example where the base name is messages and the given locale is fr_FR. Assuming that all the resource files are available in the classpath, the getBundle() method will return the following parent chain:

messages_fr_FR -> messages_fr -> messages

This means that if a key is not found in the messages_fr_FR.properties file, Java will look for it in the messages_fr.properties file, and then in the messages.properties if the key is still missing. At last, a MissingResourceException will be thrown if the key is absent from all these three files.

7. Real-world Example of Using ResourceBundle

In the following example, we use the ResourceBundle class to translate the labels of our simple Java application.
In this example, we will translate the messages in our application using three different locales: the default (English US), the French locale, and the Spanish locale. For that, we have three resource bundle files: messages.properties, message_fr.properties, and messages_es.properties. We have purposely made some keys absent from the French and Spanish Locales. In such cases, the values should be loaded from the default resource bundle.

7.1. The properties files

We are using a Maven project, and our resource bundle files are kept under src/main/resources.

# File: messages.properties
greeting = Hello!
gratitude = Thank you!
farewell = See you!

# File: messages_fr.properties
greeting = Salut!
gratitude = Merci!

# File: messages_es.properties
greeting = ¡Hola!
farewell = ¡Hasta pronto!

7.2. The Java Code

public class ResourceBundleClass {
    public static void main(String[] args) {
        realWorldExample();
    }
    
    static void realWorldExample(){
        Locale[] supportedLocales = {Locale.getDefault(),Locale.FRENCH, Locale.of("es")};
        for(Locale locale : supportedLocales){
            retrievePropertiesForLocale(locale);
        }
    }
    static void retrievePropertiesForLocale(Locale locale){
        ResourceBundle properties = ResourceBundle.getBundle("messages", locale);
        String greeting = properties.getString("greeting");
        String gratitude = properties.getString("gratitude");
        String farewell = properties.getString("farewell");
        System.out.println("********Displaying properties for Locale : "+locale);
        System.out.println("Greeting : "+greeting);
        System.out.println("Gratitude : "+gratitude);
        System.out.println("Farewell : "+farewell);
    }
}    

Run the program, and you will see an output similar to this:

********Displaying properties for Locale : en_US
Greeting : Hello!
Gratitude : Thank you!
Farewell : See you!
********Displaying properties for Locale : fr
Greeting : Salut!
Gratitude : Merci!
Farewell : See you!
********Displaying properties for Locale : es
Greeting : ¡Hola!
Gratitude : Thank you!
Farewell : ¡Hasta pronto!

As you can see, some messages from the French and Spanish languages are translated using the default Locale.

8. Conclusion

In this tutorial, you learned about the ResourceBundle class, which is the recommended class for loading property files in your Java applications.
You can find the complete code of this article here in GitHub.

Originally published at https://nkamphoa.com

Discover and read more posts from Noel KAMPHOA
get started