One of my friends asked me a few days back for how to reload the ResourceBundle in Java while the program is still executing. The first question is that why do we need to reload a ResourceBundle while runtime.

There could be various reasons for reloading a ResourceBundle in Java. To mention a few -

  1. Your program is built so as to run continuously for a longer period with different inputs at different stages.
  2. Your program is divided in to stages and the output of one stage is input of the next one. You want the inputs to only go through ResourceBundle and the always through the same one.

The above mentioned reasons are what my friend asked me for. But the second question is whether Java really does not allow us to do so. Till Java 1.5, this is not possible. This a reported defect in Java 1.5. Next release of Java i.e. 1.6 has fixed this one. Then why not use Java 1.6 instead of Java 1.5. This could be because of various reasons. I hope all Java geeks must be knowing this.

How does the ResourceBundle work?

Initially you need to load the ResourceBundle into your program -

ResourceBundle myBundle = ResourceBundle.getBundle(“myResources.properties”);

Here, myResources.properties  is a file that contains a key value pair. When you use getBundle() method of the ResourceBundle class, it loads all the data into a HashTable in the cache.

Now you can retrieve the values simply by the following code -

myBundle.getString(“key”); or myBundle.getObject(“key”);

Once loaded into the cache, this is kept till the program runs. In Java 1.5, there is no inbuilt way to clear this cache and reload the ResourceBundle.

So even if you change the values in myResources.properties file and call the getBundle() method again, the cache is not cleared and reloaded. So when you go ahead with getString() or getObject() method, you still retrieve the older values.

How to reload ResourceBundle in Java 1.5?

There is a little work around for this. You can use the following code to reload the resource. The code below uses reflection to access a private member of the ResourceBundle class and clear the cache.

//clear the cache

java.lang.Class myClass = ResourceBundle.class;

try{

        java.lang.reflect.Field cacheList = class.getDeclaredField(“cacheList”);

        cacheList.setAccessible(true);

        ((Map)cacheList.get(ResourceBundle.class)).clear();

}catch (NoSuchFieldException noSuchFieldEx) {

      System.err.println(this.getClass().getName() + ” : ” +

                               noSuchFieldEx.getMessage());

I hope this will help you to reload ResourceBundle for long running processes.

If you like the post/ solution, please leave a comment here.

  • Share/Bookmark