java getResourceAsStream 未在 webapp 中加载资源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2653322/
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
getResourceAsStream not loading resource in webapp
提问by Michael
I have a web application that uses a library which resides in TOMCAT_HOME/common/lib. This library looks for a properties file at the root of the classpath (in a class called ApplicationConfig):
我有一个 Web 应用程序,它使用驻留在 TOMCAT_HOME/common/lib 中的库。该库在类路径的根目录(在名为 ApplicationConfig 的类中)查找属性文件:
ApplicationConfig.class.getResourceAsStream("/hv-application.properties");
My Tomcat web application contains this properties file. It is in WEB-INF/classes, which is the root of the classpath right? However, at runtime, when it tries to load the properties file, it throws an exception because it can't find it (getResourceAsStream returns null).
我的 Tomcat Web 应用程序包含此属性文件。它在 WEB-INF/classes 中,它是类路径的根,对吗?但是,在运行时,当它尝试加载属性文件时,它会抛出异常,因为它找不到它(getResourceAsStream 返回 null)。
Everything works fine if my application is a simple, standalone Java application. Does Tomcat cause the getResourceAsStream method to act differently? I know there's a lot of similar questions out there, but none of them have helped unfortunately. Thanks.
如果我的应用程序是一个简单的独立 Java 应用程序,则一切正常。Tomcat 是否会导致 getResourceAsStream 方法的行为不同?我知道那里有很多类似的问题,但不幸的是,它们都没有帮助。谢谢。
回答by Binil Thomas
Try Thread.currentThread().getContextClassLoader().getResourceAsStream("/hv-application.properties")instead.
试试吧Thread.currentThread().getContextClassLoader().getResourceAsStream("/hv-application.properties")。
回答by Andy Gherna
This looks like it might be related to how Tomcat classloaders work. If you have something in one class loader (your config file in the webapp classloader) that's used by something in another (the jar in common/lib), the result could be a big headache.
这看起来可能与 Tomcat 类加载器的工作方式有关。如果你在一个类加载器(你在 webapp 类加载器中的配置文件)中有一些东西被另一个(common/lib 中的 jar)中的东西使用,结果可能会让人头疼。
This documentexplains how Tomcat delegates to class loaders. If possible, could you try one of the following:
本文档解释了 Tomcat 如何委托给类加载器。如果可能,您能否尝试以下方法之一:
- Move the jar file in common/lib into your web application (WEB-INF/lib). This is not always possible I know, but sometimes jars (e.g. log4j) can coexist peacefully across classloaders (*).
- Move your configuration file into common/classes. This is effectively the same thing (puts the configuration item into the same classloader as the jar that needs it). Again, this is not ideal, but if you have control over your environment, it would work.
- 将 common/lib 中的 jar 文件移动到您的 Web 应用程序 (WEB-INF/lib) 中。我知道这并不总是可能的,但有时 jar(例如 log4j)可以跨类加载器(*)和平共存。
- 将您的配置文件移动到 common/classes 中。这实际上是同一件事(将配置项放入与需要它的 jar 相同的类加载器中)。同样,这并不理想,但如果您可以控制您的环境,它就会起作用。
Either way, having resources in different classloaders can be a pain. I hope this helps.
无论哪种方式,在不同的类加载器中拥有资源都是一件痛苦的事情。我希望这有帮助。
(*) log4j has the -log4j.ignoreTCLoption which makes this possible though
(*) log4j 具有使-log4j.ignoreTCL这成为可能的选项
回答by stevedbrown
The Tomcat security manager generally won't let you access webapp classes and resources from libraries in the Tomcat root libraries. This is meant to give separation between the web applications running in a container.
Tomcat 安全管理器通常不会让您从 Tomcat 根库中的库访问 webapp 类和资源。这是为了在容器中运行的 Web 应用程序之间进行分离。
You should be able to get around this by updating the security policy, but it's generally better to not put your libs into the Tomcat container, which I assume you are doing.
您应该能够通过更新安全策略来解决这个问题,但通常最好不要将您的库放入 Tomcat 容器中,我假设您正在这样做。
回答by pakopa
I'm expanding Olivier commentas a response (thank you for the lead).
我正在扩展Olivier 评论作为回应(感谢您的引导)。
The problem seems to be the leading slash (/) in the resource path.
问题似乎是资源路径中的前导斜杠 (/)。
In Tomcat 8the WebAppClassloader correctly resolves the path with and without the leading slash. Both .getResourceAsStream("/org/pakopa/app/config.properties");and .getResourceAsStream("org/pakopa/app/config.properties");returns an InputStream.
在Tomcat 8 中,WebAppClassloader 正确解析带有和不带有前导斜杠的路径。双方.getResourceAsStream("/org/pakopa/app/config.properties");并.getResourceAsStream("org/pakopa/app/config.properties");返回一个InputStream。
In Tomcat 7(And I assume previous versions too) .getResourceAsStream("/org/pakopa/app/config.properties");is not resolved and returns nullbut .getResourceAsStream("org/pakopa/app/config.properties");is correctly resolved.
在Tomcat 7 中(我也假设以前的版本).getResourceAsStream("/org/pakopa/app/config.properties");未解析并返回null但.getResourceAsStream("org/pakopa/app/config.properties");已正确解析。

