在JAR中加载属性文件?
当我的网络应用程序所依赖的其中一个jar试图从jar中加载属性文件时,我遇到了麻烦。这是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. Here is the code in the jar.
static
{
Properties props = new Properties();
try
{
props.load(ClassLoader.getSystemResourceAsStream("someProps.properties"));
} catch (IOException e)
{
e.printStackTrace();
}
someProperty = props.getProperty("someKey");
}
属性文件位于我的src / main / resources目录中Maven项目。当我从Eclipse中的junit测试运行此代码时,它执行得很好。当项目使用Maven构建到jar中,并作为依赖项包含在我的Web应用程序中时,它无法找到属性文件。我知道属性文件位于依赖于jar的基本目录中,我不知道如何解决这个问题。
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.
getSystemResourceAsStream 。使用简单的 getResourceAsStream
。系统资源从系统类加载器加载,几乎可以肯定不是你的jar作为webapp运行时加载到的类加载器。
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.
它在Eclipse中有效,因为在启动应用程序时,系统类加载器配置了jar作为其类路径的一部分。 (例如,java -jar my.jar将在系统类加载器中加载my.jar。)Web应用程序不是这种情况 - 应用程序服务器使用复杂的类加载将Web应用程序彼此隔离,并与应用程序服务器的内部隔离。例如,请参阅 tomcat classloader how-to ,以及使用的类加载器层次结构图。
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.
编辑:通常,你会调用 getClass()。getResourceAsStream()
在类路径中检索资源,但是当您在静态初始化程序中获取资源时,您需要显式命名要加载的类加载器中的类。最简单的方法是使用包含静态初始化程序的类,
例如
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.
[public] class MyClass {
static
{
...
props.load(MyClass.class.getResourceAsStream("/someProps.properties"));
}
}