我有一个简单的java应用程序,它从当前包中加载属性文件。
this.getClass().getResourceAsStream("props.properties");
当我想要的属性文件在当前包中时,这可以正常工作。但是,我想将此应用程序打包为JAR,并使用我使用它的新属性文件定义和覆盖。有没有办法加载类路径上名为“props.properties”的第一个资源?
我希望通过命令行覆盖属性文件很容易:
java.exe -classpath props.properties;myJar.jar com.test.MyApp
我不想解压缩JAR并修改属性文件来更改内容。我觉得我错过了一些明显的东西......
答案 0 :(得分:26)
javadoc for Class.getResourceAsStream()
记录了查找逻辑:
如果名称以
'/'
('\u002f'
)开头,那么资源的绝对名称就是“/”后面的名称部分。否则,绝对名称的格式如下:
modified_package_name/name
modified_package_name
是此对象的包名称,其中'/'替换为'.'
('\u002e'
)。
换句话说,如果/com/package/p2/props.properties
存储在props.properties
包而不是当前类中,则传递给该方法的资源名称应该类似于com.package.p2
。
答案 1 :(得分:13)
我确定答案为时已晚,但对于谷歌来说这可能很有意思 这个小代码片段助手可以从Classpath中的任何位置加载属性文件。
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
URL url = cl.getResource(CONF_PROPERTIES);
if (url == null) {
url = cl.getResource("/" + CONF_PROPERTIES);
}
if (url != null) {
try {
InputStream in = url.openStream();
props = new Properties();
props.load(in);
} catch (IOException e) {
// Log the exception
} finally {
// close opened resources
}
}
}
答案 2 :(得分:4)
如果所有其他方法都失败了,您可以使用两个不同的文件名,例如props-default.properties
内的myJar.jar
和props.properties
来覆盖命令行。在您的代码中,您首先尝试加载props.properties
文件,如果找不到,则回退到props-default.properties
。
答案 3 :(得分:1)
我不确定,但也许:ClassLoader.getResourceAsStream()
编辑:
我认为这与问题中的this.getClass().getResourceAsStream()
没有显着差异,因为如上所述,您仍然必须获取要用于加载资源的ClassLoader。
由于您在示例中的-classpath
中提供了资源,因此它应该与您的“main”类在同一个类加载器中可用(在SUN JVM中,即sun.misc.Launcher$AppClassLoader
,不确定是否对于其他JVM实现,这可能/确实有所不同。)