从类path中的任何位置加载资源

我有一个简单的Java应用程序,从当前包加载属性文件。

this.getClass().getResourceAsStream("props.properties"); 

当我想要的属性文件在当前包中时,这工作正常。 不过,我想把这个应用程序打包成一个JAR,然后用一个新的属性文件来定义和覆盖我使用它的地方。 有没有办法加载类path上名为“props.properties”的第一个资源?

我希望它通过命令行轻松覆盖属性文件:

 java.exe -classpath props.properties;myJar.jar com.test.MyApp 

我不想打开JAR文件并修改属性文件来改变一些东西。 我觉得我失去了一些明显的东西…

如果一切都失败了,你可以使用两个不同的文件名,比如props-default.properties myJar.jarprops.properties以覆盖命令行。 在你的代码中,你会尝试先加载props.properties文件,如果props-default.properties则回props-default.properties

Class.getResourceAsStream()的javadoclogging查找逻辑:

如果名称以'/''\u002f' )开始,那么资源的绝对名称是“/”后面的名称部分。

否则,绝对名称的forms如下:
modified_package_name/name

其中modified_package_name是用“/”替代'.'对象的包名'.''\u002e' )。

换句话说,如果props.properties存储在com.package.p2包中而不是当前类中,那么传递给方法的资源名应该看起来像/com/package/p2/props.properties

我相信现在回答为时已晚,但对于谷歌来说,这个小代码片段可以帮助从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 } } } 

我不确定,但也许: ClassLoader.getResourceAsStream()

编辑:

我不认为这与this.getClass()。getResourceAsStream()的问题是显着不同的,因为如上所述,你仍然必须得到你想用来加载资源的ClassLoader。

由于您在示例中的-classpath中提供了资源,因此应该从与您的“主”类相同的类加载器中可用(在Sun JVM中,即sun.misc.Launcher $ AppClassLoader,不确定是否可以/其他JVM实现有所不同)。