Как очистить кеш ResourceBundle - PullRequest
4 голосов
/ 22 марта 2012

Это веб-приложение, работающее на Tomcat с использованием Guice. Согласно документам, мы должны иметь возможность вызвать ResourceBundle.clearCache();, чтобы очистить кэш ResourceBundle и предположительно получить последние данные из файлов свойств пакета.

Мы также попробовали следующее:

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!

и

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

Я ожидаю поведения:

  1. Запустите tomcat и перейдите на страницу с надписью «Hello World»
  2. Измените файл свойств, содержащий «Hello World», на «Goodbye Earth»
  3. Очистить кеш с помощью сервлета
  4. Зайдите на страницу и ожидайте увидеть 'Goodbye Earth'

Итак, вопрос в том, как на самом деле работает ResourceBundle.clearCache ()? И есть ли какой-нибудь общий файловый кеш, который мы также должны очистить?

Ответы [ 6 ]

6 голосов
/ 03 ноября 2014

Это сработало для меня:

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

Примечания:

  1. ResourceBundle.clearCache () добавлено в Java 1.6
  2. Не используйте статическое свойство resourceBundle, используйте метод ResourceBundle.getBundle() после вызова метода clearCache().
4 голосов
/ 22 марта 2012

Я не верю, что вы можете выполнить перезагрузку уже созданного экземпляра ResourceBundle, так как его класс внутреннего контроля уже создан.Вы можете попробовать это как альтернативу для инициализации вашего пакета:

ResourceBundle.getBundle("my.bundle", new ResourceBundle.Control() {
    @Override
    public long getTimeToLive(String arg0, Locale arg1) {
        return TTL_DONT_CACHE;
    }
});
1 голос
/ 02 июля 2013

Я нашел это решение (работает с tomcat):

  • использовать пользовательский ResourceBundle.Control (потому что мне нужен UTF8)
  • добавить getTimeToLive в качестве описания "Восприятие"
  • принудительно установить флаг перезагрузки
  • «ResourceBundle.clearCache» не работает

Как вызвать:

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

Пользовательский класс:

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;
    }
}
0 голосов
/ 02 ноября 2016

Это работает, если вы можете перехватить самое первое создание пакета ресурсов:

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 голосов
/ 01 августа 2014
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 голосов
/ 13 июня 2012

возможно этот пост может решить вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...