从classpath中的任何位置加载资源

时间:2010-07-20 20:41:30

标签: java

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

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

当我想要的属性文件在当前包中时,这可以正常工作。但是,我想将此应用程序打包为JAR,并使用我使用它的新属性文件定义和覆盖。有没有办法加载类路径上名为“props.properties”的第一个资源?

我希望通过命令行覆盖属性文件很容易:

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

我不想解压缩JAR并修改属性文件来更改内容。我觉得我错过了一些明显的东西......

4 个答案:

答案 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.jarprops.properties来覆盖命令行。在您的代码中,您首先尝试加载props.properties文件,如果找不到,则回退到props-default.properties

答案 3 :(得分:1)

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

编辑:

我认为这与问题中的this.getClass().getResourceAsStream()没有显着差异,因为如上所述,您仍然必须获取要用于加载资源的ClassLoader。

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