【问题标题】:JSF2.0 ResourceBundle needs to be reloaded without server restartJSF2.0 ResourceBundle 需要重新加载而不需要重新启动服务器
【发布时间】:2011-03-30 17:57:23
【问题描述】:

我们使用 JSF2.0 和 JDK1.6 和 Tomcat6.1

我们需要在不重新启动服务器的情况下更新属性文件值(由 JSF 资源包加载),以便不会停止实时 Web 会话。

JDK1.6 可以吗,我尝试了下面的 clearCache 代码,但是没有用。

ResourceBundle bundle = ResourceBundle.getBundle("Label");
String s = bundle.getString("profile.firstName");
out.println("Value before: %"+ s);
ResourceBundle.clearCache(Thread.currentThread().getContextClassLoader());
bundle = ResourceBundle.getBundle("Label");
s = bundle.getString("profile.firstName");
out.println("Value after: {}"+s);

以前有没有人尝试过。

更新

下面似乎没有解决重新加载资源包的问题

ResourceBundle.clearCache(Thread.currentThread().getContextClassLoader());
ApplicationResourceBundle applicationBundle = ApplicationAssociate.getCurrentInstance().getResourceBundles().get("Label");
Field field = applicationBundle.getClass().getDeclaredField("resources");
field.setAccessible(true);
Map<Locale, ResourceBundle> resources = (Map<Locale, ResourceBundle>) field.get(applicationBundle);
resources.clear();

我错过了什么吗?

【问题讨论】:

  • 您确定您拥有正确捆绑包的句柄吗?代码中的“标签”字符串需要替换为您的捆绑包。我断点了这段代码并为 ApplicationAssociate.getCurrentInstance().getResourceBundles() 添加了一个监视,然后查看了其中的内容。
  • 顺便说一句,我正在使用 JSF2、JDK1.6、Glassfish 3.1.1

标签: java tomcat jsf-2 resourcebundle


【解决方案1】:

这曾经适用于一些 JSF 实现/版本。然而,在最近的 Mojarra 版本中,缓存机制在实现本身中多了一层。假设你确实在使用 Mojarra,除了这一行

ResourceBundle.clearCache(Thread.currentThread().getContextClassLoader());

你也需要这样做,从com.sun.faces.application.ApplicationAssociate开始

ApplicationResourceBundle applicationBundle = ApplicationAssociate.getCurrentInstance().getResourceBundles().get("Label");
Field field = applicationBundle.getClass().getDeclaredField("resources");
field.setAccessible(true);
Map<Locale, ResourceBundle> resources = (Map<Locale, ResourceBundle>) field.get(applicationBundle);
resources.clear();

是的,这是一个 hack,但 JSF 没有提供任何干净的 API 方法来实现同样的目标。

【讨论】:

  • 根据您的“答案”(应作为对此答案的评论或问题的更新发布),您因此获得了 NPE。您需要更清楚 null 到底是什么。是applicationBundle吗?还是getDeclaredField() 返回null?你确定你是在 JSF 上下文中运行它而不是作为普通的应用程序或其他东西吗?至于示例,请注意我在答案中使用了捆绑名称 Label,与您在问题中使用的完全相同。
  • 我使用了您在第一个答案中提到的代码。我从 servlet 调用了清除缓存代码。我现在没有得到 NPE。但它没有刷新 values 。我的一个问题是,你得到的是 getDeclaredField("resources") ,是属性文件中的 "resources" 字段。
  • 不,它是 ApplicationResourceBundle 类的私有字段。您到底在使用什么 JSF impl/version?这适用于 Mojarra 2.0.3。
  • 请编辑您的问题以提供更多信息,或使用评论字段要求澄清答案。答案字段仅用于回答您的问题。
  • 如果您自己找到了答案,您有义务将其作为您自己问题的答案发布,以便该问题对其他人有用。
猜你喜欢
  • 2014-03-01
  • 2016-08-20
  • 2013-06-25
  • 2014-05-09
  • 2014-09-05
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多