How to clear ResourceBundle resource cache

This webapp runs on Tomcat using Guice. According to the docs, we can call ResourceBundle.clearCache(); to clear the ResourceBundle cache and apparently get the latest data from the package properties files.

We also tried the following:

 Class klass = ResourceBundle.getBundle("my.bundle").getClass().getSuperclass(); Field field = klass.getDeclaredField("cacheList"); field.setAccessible(true); ConcurrentHashMap cache = (ConcurrentHashMap) field.get(null); cache.clear(); // If i debug here I can see the cache is now empty! 

and

 ResourceBundle.clearCache(this.class.getClassLoader()); 

The behavior I expect is as follows:

  • Launch tomcat and click on the page and it says "Hello World".
  • Change the properties file containing "Hello World" to "Goodbye Earth"
  • Clear cache with servlet
  • Click on the page and expect to see "Goodbye."

So the question is, how does ResourceBundle.clearCache () work? And is there some kind of general file cache that we need to clear as well?

+4
source share
6 answers

This worked for me:

 ResourceBundle.clearCache(); ResourceBundle resourceBundle= ResourceBundle.getBundle("YourBundlePropertiesFile"); String value = resourceBundle.getString("your_resource_bundle_key"); 

Notes:

  • ResourceBundle.clearCache () added in Java 1.6
  • Do not use the static resourceBundle property, use ResourceBundle.getBundle() after calling the clearCache() method.
+5
source

I do not believe that you can reload an already created instance of ResourceBundle, since its internal management class has already been created. You can try this as an alternative to initializing your package:

 ResourceBundle.getBundle("my.bundle", new ResourceBundle.Control() { @Override public long getTimeToLive(String arg0, Locale arg1) { return TTL_DONT_CACHE; } }); 
+4
source

maybe this post may solve your problem.

+1
source

I found this solution (works with tomcat):

  • use custom ResourceBundle.Control (because I need UTF8)
  • add getTimeToLive as the Perception description
  • force reload flag
  • "ResourceBundle.clearCache" does not work.

How to call:

 ResourceBundle bundle = ResourceBundle.getBundle("yourfile", new UTF8Control()); 

Custom class:

 public class UTF8Control extends Control { public ResourceBundle newBundle( String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException { // The below is a copy of the default implementation. String bundleName = toBundleName(baseName, locale); String resourceName = toResourceName(bundleName, "properties"); ResourceBundle bundle = null; InputStream stream = null; // FORCE RELOAD because needsReload doesn't work and reload is always false reload = true; if (reload) { URL url = loader.getResource(resourceName); if (url != null) { URLConnection connection = url.openConnection(); if (connection != null) { connection.setUseCaches(false); stream = connection.getInputStream(); } } } else { stream = loader.getResourceAsStream(resourceName); } if (stream != null) { try { // Only this line is changed to make it to read properties files as UTF-8. bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8")); } finally { stream.close(); } } return bundle; } // ASK NOT TO CACHE public long getTimeToLive(String arg0, Locale arg1) { return TTL_DONT_CACHE; } } 
+1
source
 this is one more possibility to clear cache Class<ResourceBundle> type = ResourceBundle.class; try { Field cacheList = type.getDeclaredField("cacheList"); cacheList.setAccessible(true); ((Map<?, ?>) cacheList.get(ResourceBundle.class)).clear(); } catch (Exception e) { system.out.print("Failed to clear ResourceBundle cache" + e); } 
0
source

This works if you can intercept the very first creation of a resource package:

 while (true) { ResourceBundle resourceBundle = ResourceBundle.getBundle("SystemMessages", new Locale("hu", "HU"), new ResourceBundle.Control() { @Override public List<String> getFormats(String baseName) { return ResourceBundle.Control.FORMAT_PROPERTIES; } @Override public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException { System.err.println(this.toBundleName(baseName, locale) + ": " + format + " - " + reload); return super.newBundle(baseName, locale, format, loader, reload); } @Override public long getTimeToLive(String baseName, Locale locale) { long ttl = 1000; System.err.println(this.toBundleName(baseName, locale) + " - " + ttl + "ms"); return ttl; } @Override public boolean needsReload(String baseName, Locale locale, String format, ClassLoader loader, ResourceBundle bundle, long loadTime) { System.err.println(baseName + "_" + locale + " - " + new Date(loadTime)); return true; } }); System.out.println(resourceBundle.getString("display.first_name") + ": John"); System.out.println(resourceBundle.getString("display.last_name") + ": Doe"); Thread.sleep(5000); } 
0
source

Source: https://habr.com/ru/post/1402848/


All Articles