Java 从类路径中的任何位置加载资源

Java 从类路径中的任何位置加载资源,java,Java,我有一个简单的java应用程序,它从当前包中加载属性文件 this.getClass().getResourceAsStream("props.properties"); 当我想要的属性文件在当前包中时,这可以正常工作。但是,我想将这个应用程序打包为一个JAR,并在使用它的地方定义和覆盖一个新的属性文件。有没有办法加载类路径上第一个名为“props.properties”的资源 我希望通过命令行可以轻松覆盖属性文件: java.exe -classpath props.properties;m

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

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

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

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

我不想非要解包JAR并修改属性文件来更改某些内容。我觉得我遗漏了一些明显的东西…

我不确定,但可能:
ClassLoader.getResourceAsStream()

编辑:

我不认为这与问题中的
this.getClass().getResourceAsStream()
有什么显著不同,因为正如前面提到的,您仍然需要获取要用于加载资源的类加载器

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

如果名称以“/”开头(
'\u002f'
),则资源的绝对名称是名称“/”后面的部分

否则,绝对名称的形式如下:
modified\u package\u name/name

其中,
modified\u package\u name
是此对象的包名,用“/”代替了
'\u002e'


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

如果所有其他操作都失败,则可以使用两个不同的文件名,在
myJar.jar
props.properties
中说
props default.properties
,以在命令行上覆盖。在您的代码中,您可以尝试先加载
props.properties
文件,如果找不到它,则返回到
props default.properties

我敢肯定,现在回答这个问题已经太晚了,但这可能会让谷歌用户感兴趣 这个小代码段帮助您从类路径中的任何位置加载属性文件

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.getSystemClassLoader()
-顾名思义,它是其他类的“老板”。在
ClassLoader
类中没有静态方法
getResourceAsStream()
。系统ClassLoader可能会从应用程序的类路径之外加载资源,例如,在JRE安装路径正确的引导目录中查找,
ClassLoader.getsystemresourceastream()
ClassLoader.getSystemClassLoader().getresourceastream()的缩写,对于
props.properties
/com/test/props.properties
这两个属性,它都返回null。一种常见的方法是直接从应用程序类加载器(负责“-classpath”)加载它:sun.misc.Launcher$AppClassLoader.getAppClassLoader(sun.misc.Launcher$ExtClassLoader.getExtClassLoader()).getResourceAsStream(…);可能不可移植。您不使用getResourceAsStream有什么具体原因吗?我在开发EE应用程序时使用这种初始化。在开发过程中,我的应用程序知道该文件抛出Eclipse类路径。但是在创建EAR时,应用程序知道该文件抛出类路径配置抛出WebSphere。我也会很感激另一个优雅的解决方案。我明白了。我没有料到这会引发不同的异常(或者至少会料到它们都有一个共同的父级,比如IOException)。不过这是一种有趣的方法。我不认为这实际上是从类路径的任何地方加载属性文件;matt b的回答中引用的文档说,它将从当前包或根目录加载文件,但不会从类路径中的任何位置加载。在maven项目中,当资源位于测试文件夹中时,它对我不起作用。