如何将外部文件加载到类路径Play Framework 2.3中

时间:2015-10-28 00:35:45

标签: java classpath classloader playframework-2.3 properties-file

我需要使用Play Framework 2.3(Java)将外部文件加载到类路径中

规定:

  • 外部文件无法在我的Play应用程序中生效(即/conf/lib目录等不是一个选项。

  • 该文件必须是.properties.conf文件,因此我可以指定属性值

这是我的情景:

  • 我有一个自定义JAR,它有一些代码,在使用时会在类路径中查找特定文件(让我们称之为myproperties.properties)。我尝试查找myproperties.properties的方法是在一个驻留在该自定义JAR中的类中执行此操作:

    ClassLoader classLoader = com.my.package.MyCustomJavaClass.class.getClassLoader();
    InputStream inputStream = classLoader.getResourceAsStream("/path/to/myproperties.properties");
    

    我有权在JAR中更改属性文件名及其路径。

  • 我的Play框架应用程序(使用Java)在其/lib文件夹中包含此自定义JAR,因此它会自动添加到类路径中(这已经过测试并且可以正常工作)。我的Play应用程序在第一次加载/路径(索引路径)时调用MyCustomJavaClass,因此当我在浏览器中点击我的播放应用程序时,上面的类加载器和输入流代码将被启动。

问题:

  • 尝试以自定义JAR中的代码可以看到的方式启动Play App时,我尝试将/path/to/myproperties.properties加载到类路径中并没有成功。

    我一直试图尝试使用类路径命令来尝试向JVM提供外部文件:

    activator start -J-classpath "-J-classpath:/path/to/myproperties.properties"
    

    我将-J-classpath;添加到路径的开头,尝试复制当前在类路径中的所有内容,然后只添加我的单个外部文件。但是,这样做似乎不起作用(即我的inputStream为null)。

问题:

  • 启动播放应用时,我是否正确执行activator start -J-classpath命令?尝试复制现有类路径的其他变体不允许播放应用程序启动,但此命令至少启动了我的应用程序。

    参考(指定其他JVM参数):https://www.playframework.com/documentation/2.3.x/ProductionConfiguration

  • 我可以通过其他方式完成这项工作吗?我已经探索过使用application.conf覆盖activator start -Dconfig.file=/path/to/application-override.conf文件并将我的属性放在新的application-override.conf文件中。但是,似乎并没有将该文件放入MyCustomJavaClass的类路径中以使用类加载器进行查找。也许我也错误地执行了这个命令?

  • Play Framework类路径是否可能与我的自定义JAR看到的类路径分开?我一直假设它在一个JVM和类路径中。

1 个答案:

答案 0 :(得分:0)

这是我提出的解决方案,希望它可以帮助其他人:

  • 在我的"上层环境" (AWS服务器)部署了我的播放应用程序,我将application-override.conf文件放在播放框架应用程序目录的conf文件夹中

  • application-override.conf与我的application.conf完全相同,但我在游戏应用程序所处的每个环境中都有一些自定义属性值

  • 我的播放框架应用程序是一个git仓库,它被克隆在每个上层环境中,所以我将application-override.conf添加到.gitignore(我不想让它检查到回购所以它只存在于服务器上)

  • 启动播放应用时,我现在使用activator start "-Dconfig.trace=loads -Dconfig.file=conf/application-override.conf"。这将使用application.conf覆盖application-override.conf文件,application-override.conf将位于播放用于运行应用程序的JVM类路径中(因为它位于conf目录中)。 -Dconfig.trace=loads会发出更多日志记录,以告知您.conf文件是否正确加载;如果一切正常,它不是必要的标志。

  • 在java方面,在我的自定义JAR中,我现在可以执行以下操作:

    Properties properties;
    InputStream stream;
    ClassLoader classLoader = com.my.package.MyCustomJavaClass.class.getClassLoader();
    
    // first, look for application-override.conf in the classpath (upper environments)
    stream = classLoader.getResourceAsStream("application-override.conf");
    
    // if null, check for application.conf (local environment)
    if (stream == null) {
        stream = classLoader.getResourceAsStream("application.conf");
    }
    
    properties = new Properties();
    properties.load(stream);
    stream.close();
    

其他说明:

  • 我考虑在conf目录中执行符号链接/软链接,并将application-override.conf文件放在我的环境中的其他位置,但在Play 2.4之前,您无法拥有conf目录中的符号链接,所以我只将实际的application-override.conf文件放在conf文件夹中

  • application-override.conf文件对于每个"上层环境"具有不同的属性值,否则我只是将一个覆盖文件传递给git repo。在自定义JAR中,我不想放入寻找不同文件名的逻辑,例如dev-override.confpre-prod-override.confprod-override.conf等。我想要一个单一的上层环境覆盖文件。

  • -classpath=/path/to/myproperties.properties-J-classpath=/path/to/myproperties.properties命令与activator start一起取得了成功。我也没有成功尝试附加到类路径,例如activator start -J-classpath=-J-classpath:/path/to/myproperties.properties或其他类似组合

  • application-override.conf文件中放置属性的路线实际上为我打了两只鸟,因为我一直希望通过覆盖.conf文件来进行一些特定于环境的更改我的每个环境以及自定义属性

  • 由于我的属性值的性质,.conf文件的HOCON格式要求我在属性值周围加上双引号。在阅读Java中的那些属性时,引号仍然适用于我,因此在阅读这些属性时我必须执行str.replace("\"","")