简体   繁体   English

在JAR中加载属性文件?

[英]Load properties file in JAR?

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. 当我的网络应用程序所依赖的其中一个罐试图从jar中加载属性文件时,我遇到了麻烦。 Here is the code in the 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. 属性文件位于Maven项目的“src / main / resources”目录中。 When I run this code from my junit test in Eclipse, it executes just fine. 当我在Eclipse中的junit测试中运行此代码时,它执行得很好。 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. 当项目使用Maven构建到jar中,并作为依赖项包含在我的Web应用程序中时,它无法找到属性文件。 I know that the properties file is at the base directory of the depended on jar, I don't know how to fix this. 我知道属性文件位于依赖于jar的基本目录中,我不知道如何解决这个问题。

The problem is that you are using getSystemResourceAsStream . 问题是您正在使用getSystemResourceAsStream Use simply getResourceAsStream . 使用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. 系统资源从系统类加载器加载,几乎可以肯定不是在作为webapp运行时加载jar的类加载器。

It works in Eclipse because when launching an application, the system classloader is configured with your jar as part of its classpath. 它在Eclipse中工作,因为在启动应用程序时,系统类加载器配置为您的jar作为其类路径的一部分。 (Eg 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. (例如,java -jar my.jar将在系统类加载器中加载my.jar。)Web应用程序不是这种情况 - 应用程序服务器使用复杂的类加载将Web应用程序彼此隔离,并与应用程序服务器的内部隔离。 For example, see the tomcat classloader how-to , and the diagram of the classloader hierarchy used. 例如,请参阅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. 编辑:通常,您可以调用getClass().getResourceAsStream()来检索类路径中的资源,但是当您在静态初始化程序中获取资源时,您需要显式命名您想要的类加载器中的类。从...加载。 The simplest approach is to use the class containing the static initializer, eg 最简单的方法是使用包含静态初始化程序的类,例如

[public] class MyClass {
  static
  {
    ...
    props.load(MyClass.class.getResourceAsStream("/someProps.properties"));
  }
}

For the record, this is documented in How do I add resources to my JAR? 有关记录,请参阅如何向JAR添加资源? (illustrated for unit tests but the same applies for a "regular" resource): (图示为单元测试,但同样适用于“常规”资源):

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 . 要为单元测试的类路径添加资源,您将遵循与向JAR添加资源相同的模式,除了您放置资源的目录是${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 ... 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM