[英]Load resource from anywhere in classpath
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.
但是,我想将此应用程序打包为JAR,并在使用它的地方用新的属性文件定义和覆盖。 Is there a way to load the first resource named "props.properties" that is on the classpath?
有没有办法加载类路径上名为“ 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. 我不想解压缩JAR并修改属性文件以更改某些内容。 I feel like I'm missing something obvious...
我觉得我缺少明显的东西...
The javadoc for Class.getResourceAsStream()
documents the lookup logic: Class.getResourceAsStream()
的Javadoc记录了查找逻辑:
If the name begins with a
'/'
('\/'
), 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_name
is the package name of this object with '/' substituted for'.'
其中
modified_package_name
是此对象的软件包名称,用“ /”代替'.'
('\.'
).(
'\.'
)。
So in other words, the resource name passed to the method should look like /com/package/p2/props.properties
if the props.properties
is stored in the com.package.p2
package instead of the current class's. 因此,换句话说,如果
props.properties
存储在com.package.p2
包中而不是当前类的包中,则传递给该方法的资源名称应类似于/com/package/p2/props.properties
。
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. 我确定答案为时已晚,但是对于Google员工来说,这个小代码段帮助程序可以从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
}
}
}
If all else fails you could use two different file names, say props-default.properties
inside myJar.jar
and props.properties
to override on the command-line. 如果所有其他方法均失败,则可以使用两个不同的文件名,例如
props-default.properties
myJar.jar
和props.properties
在命令行上覆盖。 In your code, you'd try loading the props.properties
file first and fallback to props-default.properties
if it wasn't found. 在您的代码中,您将尝试首先加载
props.properties
文件,如果找不到该文件,则回props-default.properties
。
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 -classpath
in 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实现而异)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.