Java 在 JAR 中加载属性文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2815404/
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
Load properties file in JAR?
提问by Andy
I'm having trouble when one of the jars that my web app depends on tries to load a properties file from within the jar. Here is the code in the jar.
当我的 Web 应用程序所依赖的 jar 之一尝试从 jar 中加载属性文件时,我遇到了问题。这是jar中的代码。
static
{
Properties props = new Properties();
try
{
props.load(ClassLoader.getSystemResourceAsStream("someProps.properties"));
} catch (IOException e)
{
e.printStackTrace();
}
someProperty = props.getProperty("someKey");
}
The properties file is in my "src/main/resources" directory of the Maven project. When I run this code from my junit test in Eclipse, it executes just fine. When the project is built with Maven into a jar, and included as a dependency in my web app, it fails to locate the properties file. I know that the properties file is at the base directory of the depended on jar, I don't know how to fix this.
属性文件位于 Maven 项目的“src/main/resources”目录中。当我从 Eclipse 中的 junit 测试运行此代码时,它执行得很好。当项目使用 Maven 构建到 jar 中,并作为依赖项包含在我的 Web 应用程序中时,它无法找到属性文件。我知道属性文件位于依赖的 jar 的基本目录中,我不知道如何解决这个问题。
采纳答案by mdma
The problem is that you are using getSystemResourceAsStream
. Use simply getResourceAsStream
. System resources load from the system classloader, which is almost certainly not the class loader that your jar is loaded into when run as a webapp.
问题是您正在使用getSystemResourceAsStream
. 简单地使用getResourceAsStream
。系统资源从系统类加载器加载,这几乎肯定不是你的 jar 作为 webapp 运行时加载到的类加载器。
It works in Eclipse because when launching an application, the system classloader is configured with your jar as part of its classpath. (E.g. java -jar my.jar will load my.jar in the system class loader.) This is not the case with web applications - application servers use complex class loading to isolate webapplications from each other and from the internals of the application server. For example, see the tomcat classloader how-to, and the diagram of the classloader hierarchy used.
它在 Eclipse 中有效,因为在启动应用程序时,系统类加载器将您的 jar 配置为其类路径的一部分。(例如 java -jar my.jar 将在系统类加载器中加载 my.jar。)Web 应用程序不是这种情况 - 应用程序服务器使用复杂的类加载来将 Web 应用程序彼此隔离并与应用程序服务器的内部隔离。例如,请参阅tomcat 类加载器操作方法以及所使用的类加载器层次结构图。
EDIT: Normally, you would call getClass().getResourceAsStream()
to retrieve a resource in the classpath, but as you are fetching the resource in a static initializer, you will need to explicitly name a class that is in the classloader you want to load from. The simplest approach is to use the class containing the static initializer,
e.g.
编辑:通常,您会调用getClass().getResourceAsStream()
以检索类路径中的资源,但是当您在静态初始值设定项中获取资源时,您需要显式命名要从中加载的类加载器中的类。最简单的方法是使用包含静态初始化器的类,例如
[public] class MyClass {
static
{
...
props.load(MyClass.class.getResourceAsStream("/someProps.properties"));
}
}
回答by Pascal Thivent
For the record, this is documented in How do I add resources to my JAR?(illustrated for unit tests but the same applies for a "regular" resource):
作为记录,这在如何将资源添加到我的 JAR 中进行了记录?(说明为单元测试,但同样适用于“常规”资源):
To add resources to the classpath for your unit tests, you follow the same pattern as you do for adding resources to the JAR except the directory you place resources in is
${basedir}/src/test/resources
. At this point you would have a project directory structure that would look like the following:my-app |-- pom.xml `-- src |-- main | |-- java | | `-- com | | `-- mycompany | | `-- app | | `-- App.java | `-- resources | `-- META-INF | |-- application.properties `-- test |-- java | `-- com | `-- mycompany | `-- app | `-- AppTest.java `-- resources `-- test.properties
In a unit test you could use a simple snippet of code like the following to access the resource required for testing:
... // Retrieve resource InputStream is = getClass().getResourceAsStream("/test.properties" ); // Do something with the resource ...
要将资源添加到单元测试的类路径中,您可以遵循与将资源添加到 JAR 相同的模式,除了将资源放入的目录是
${basedir}/src/test/resources
. 此时,您将拥有一个如下所示的项目目录结构:my-app |-- pom.xml `-- src |-- main | |-- java | | `-- com | | `-- mycompany | | `-- app | | `-- App.java | `-- resources | `-- META-INF | |-- application.properties `-- test |-- java | `-- com | `-- mycompany | `-- app | `-- AppTest.java `-- resources `-- test.properties
在单元测试中,您可以使用如下所示的简单代码片段来访问测试所需的资源:
... // Retrieve resource InputStream is = getClass().getResourceAsStream("/test.properties" ); // Do something with the resource ...