【问题标题】:Is it possible to supply a new PropertiesConfiguration file at runtime?是否可以在运行时提供新的 PropertiesConfiguration 文件?
【发布时间】:2012-04-12 18:47:34
【问题描述】:

背景:

我要求向用户显示的消息必须因语言和公司部门而异。因此,我不能使用开箱即用的资源包,所以我实际上是在使用 PropertiesConfiguration 文件编写我自己的资源包版本。

此外,我有一个要求,即消息必须在生产中动态修改而无需重新启动。

我正在加载三个不同的属性文件迭代:

-basename_division.properties
-basename_2CharLanguageCode.properties
-basename.properties

这些文件存在于类路径中。此代码将进入一个标签库,供 Portal 中的多个 portlet 使用。

我构建了可能的 .properties 文件,然后尝试通过以下方式加载每个文件:

PropertiesConfiguration configurationProperties;
try {
    configurationProperties = new PropertiesConfiguration(propertyFileName);
    configurationProperties.setReloadingStrategy(new FileChangedReloadingStrategy());
} catch (ConfigurationException e) {
    /* This is ok -- it just means that the specific configuration file doesn't 
       exist right now, which will often be true. */
    return(null);
}

如果它确实成功地找到了一个文件,它会将创建的 PropertiesConfiguration 保存到一个 hashmap 中以供重复使用,然后尝试找到 key。 (与常规资源包不同,如果找不到密钥,它会尝试查找更通用的文件以查看该文件中是否存在密钥 - 因此只需将覆盖异常放入语言/部门特定属性文件。)

问题:

如果文件在第一次检查时不存在,则会引发预期的异常。但是,如果稍后将文件放入类路径中并且然后重新运行此代码,则仍然会引发异常。重新启动门户显然可以解决问题,但这对我没有用 - 我需要能够允许他们将新消息放置在适当的位置,以便无需重新启动即可覆盖语言/公司部门。而且我对为所有可能的部门创建空白文件并不感兴趣,因为有很多部门。

我假设这是一个类加载器问题,因为它第一次确定该文件在类路径中不存在,并在尝试重新加载同一文件时缓存该结果。我对使用类加载器做任何太花哨的事情不感兴趣。 (我将是唯一能够理解/维护该代码的人。)具体环境是 WebSphere Portal。

有什么办法可以解决这个问题还是我被卡住了?

【问题讨论】:

    标签: java apache-commons apache-commons-config


    【解决方案1】:

    我的猜测是我不确定 Apache 的 FileChangedReloadingStrategy 是否也报告了文件系统目录上的 ENTRY_CREATE 事件。

    如果您使用的是 Java 7,我建议尝试以下方法。简单地说,使用 Java 7 WatchService 实现一个新的 ReloadingStrategy。这样,每次在目标目录中更改文件或将新的属性文件放置在那里时,您poll 就可以为该事件添加属性并添加到您的应用程序中。

    如果不是在 Java 7 上,也许使用诸如 JNotify 之类的库将是一个更好的解决方案来获取目录中的新条目事件。但同样,您需要实现ReloadingStrategy

    更新适用于 Java 6:

    PropertiesConfiguration configurationProperties;
    try {
        configurationProperties = new PropertiesConfiguration(propertyFileName);
        configurationProperties.setReloadingStrategy(new FileChangedReloadingStrategy());
    } catch (ConfigurationException e) {
        JNotify.addWatch(propertyFileDirectory, JNotify.FILE_CREATED, false, new FileCreatedListener());
    }
    

    在哪里

    class FileCreatedListener implements JNotifyListener {
      // other methods
    
      public void fileCreated(int watchId, String rootPath, String fileName) {
        configurationProperties = new PropertiesConfiguration(rootPath + "/" + fileName);
        configurationProperties.setReloadingStrategy(new FileChangedReloadingStrategy());
        // or any other business with configurationProperties
      }
    
    }
    

    【讨论】:

    • 其实ConfigurationException是在构造函数上抛出的。而且我永远不会停止收到异常,即使该文件已被删除。所以,实现我自己的FileChangedReloadingStrategy 不会直接帮助。 (在我的例子中,它是 Java 6)。
    • 我相信接收异常是有道理的。 FileChangedReloadingStrategy 用于监视“文件更改”,这意味着您假设文件已经存在;因此它不会报告在目录中删除的新文件,因为它以前不存在。这就是为什么我认为您需要修改版本,让我们称之为NewFileReloadingStrategy 来捕获新文件被放入目录中的事件。由于您使用的是 Java 6,因此尝试 JNotify 是否可以让您接收目录中新文件的事件?
    • 现在更有意义了——我没明白你之前的意思。这个周末我会试着把它放在一起,看看它是否能按预期工作。
    猜你喜欢
    • 1970-01-01
    • 2012-06-28
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多