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