是否可以在运行时提供新的PropertiesConfiguration文件?

时间:2012-03-29 06:16:58

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

背景

我要求显示给用户的消息必须根据语言和公司分部而变化。因此,我不能使用开箱即用的资源包,所以我实际上是使用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中以供重用,然后尝试查找该密钥。 (与常规资源包不同,如果找不到密钥,则会尝试查找更通用的文件以查看该文件中是否存在密钥 - 因此只需覆盖异常需要放入特定于语言/部门的属性中文件。)

问题:

如果文件在第一次检查时不存在,则会抛出预期的异常。但是,如果以后稍后将文件放入类路径中,然后重新运行此代码,则仍会抛出异常。重新启动门户网站显然可以解决问题,但这对我没用 - 我需要能够允许他们在没有重启的情况下为语言/ companyDivision覆盖删除新消息。我并不感兴趣为所有可能的部门创建空白文件,因为有很多部门。

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

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

1 个答案:

答案 0 :(得分: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
  }

}