我需要使用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和类路径中。
答案 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.conf
,pre-prod-override.conf
,prod-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("\"","")