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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3294196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 21:48:48  来源:igfitidea点击:

Load resource from anywhere in classpath

java

提问by schmimd04

I have a simple java application that loads a properties file from the current package.

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

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

This works fine when the property file I want is in the current package. However, I want to package this application as a JAR and define and override with a new properties file where I use it. Is there a way to load the first resource named "props.properties" that is on the classpath?

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

I want it to be as easy to override the properties file via command line:

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

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

I don't want to have to unpack the JAR and modify the properties file to change something. I feel like I'm missing something obvious...

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

采纳答案by Mike Tunnicliffe

If all else fails you could use two different file names, say props-default.propertiesinside myJar.jarand props.propertiesto override on the command-line. In your code, you'd try loading the props.propertiesfile first and fallback to props-default.propertiesif it wasn't found.

如果所有其他方法都失败了,您可以使用两个不同的文件名,例如props-default.propertiesinsidemyJar.jarprops.properties在命令行上覆盖。在您的代码中,您会尝试先加载props.properties文件,props-default.properties如果未找到则回退。

回答by Mike Tunnicliffe

I'm not sure, but maybe: ClassLoader.getResourceAsStream()

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

EDIT:

编辑:

I don't think this is significantly different to this.getClass().getResourceAsStream()from the question, since as mentioned you still have to get the ClassLoader you want to use to load the resource.

我不认为这this.getClass().getResourceAsStream()与问题有很大不同,因为如前所述,您仍然必须获得要用于加载资源的 ClassLoader。

Since you provide the resource in the -classpathin your example, it should be available from the same class loader as your "main" class (in the SUN JVM, that's sun.misc.Launcher$AppClassLoader, not sure if this can/does vary for other JVM implementations).

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

回答by matt b

The javadoc for Class.getResourceAsStream()documents the lookup logic:

用于Class.getResourceAsStream()记录查找逻辑的javadoc

If the name begins with a '/'('\u002f'), then the absolute name of the resource is the portion of the name following the '/'.

Otherwise, the absolute name is of the following form:
modified_package_name/name

Where the modified_package_nameis the package name of this object with '/' substituted for '.'('\u002e').

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

否则,绝对名称采用以下形式:
modified_package_name/name

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

So in other words, the resource name passed to the method should look like /com/package/p2/props.propertiesif the props.propertiesis stored in the com.package.p2package instead of the current class's.

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

回答by Abderrazak BOUADMA

I'm sure it's too late for the answer but it could be interesting for googlers this small code snippet helpers to load a properties file from any where in the 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
            }

        }
    }