简体   繁体   English

getResourceAsStream没有在webapp中加载资源

[英]getResourceAsStream not loading resource in webapp

I have a web application that uses a library which resides in TOMCAT_HOME/common/lib. 我有一个Web应用程序,它使用驻留在TOMCAT_HOME / common / lib中的库。 This library looks for a properties file at the root of the classpath (in a class called ApplicationConfig): 此库在类路径的根(在名为ApplicationConfig的类中)中查找属性文件:

ApplicationConfig.class.getResourceAsStream("/hv-application.properties");

My Tomcat web application contains this properties file. 我的Tomcat Web应用程序包含此属性文件。 It is in WEB-INF/classes, which is the root of the classpath right? 它在WEB-INF / classes中,它是classpath的根本吗? However, at runtime, when it tries to load the properties file, it throws an exception because it can't find it (getResourceAsStream returns null). 但是,在运行时,当它尝试加载属性文件时,它会抛出异常,因为它无法找到它(getResourceAsStream返回null)。

Everything works fine if my application is a simple, standalone Java application. 如果我的应用程序是一个简单的独立Java应用程序,那么一切正常。 Does Tomcat cause the getResourceAsStream method to act differently? Tomcat会导致getResourceAsStream方法采取不同的行为吗? I know there's a lot of similar questions out there, but none of them have helped unfortunately. 我知道那里有很多类似的问题,但不幸的是他们都没有帮助过。 Thanks. 谢谢。

请尝试使用Thread.currentThread().getContextClassLoader().getResourceAsStream("/hv-application.properties")

This looks like it might be related to how Tomcat classloaders work. 这看起来可能与Tomcat类加载器的工作方式有关。 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. 如果你在一个类加载器(webapp类加载器中的配置文件)中有某些东西被另一个(jar in common / lib)中的东西使用,那么结果可能会非常令人头疼。

This document explains how Tomcat delegates to class loaders. 文档解释了Tomcat如何委托给类加载器。 If possible, could you try one of the following: 如果可能,您可以尝试以下之一:

  1. Move the jar file in common/lib into your web application (WEB-INF/lib). 将common / lib中的jar文件移动到Web应用程序(WEB-INF / lib)中。 This is not always possible I know, but sometimes jars (eg log4j) can coexist peacefully across classloaders (*). 我知道这并不总是可行的,但有时jars(例如log4j)可以跨类加载器(*)和平共存。
  2. Move your configuration file into common/classes. 将配置文件移动到common / classes中。 This is effectively the same thing (puts the configuration item into the same classloader as the jar that needs it). 这实际上是相同的(将配置项放入与需要它的jar相同的类加载器中)。 Again, this is not ideal, but if you have control over your environment, it would work. 同样,这并不理想,但如果你能控制你的环境,那就行了。

Either way, having resources in different classloaders can be a pain. 无论哪种方式,在不同的类加载器中拥有资源可能会很痛苦。 I hope this helps. 我希望这有帮助。

(*) log4j has the -log4j.ignoreTCL option which makes this possible though (*)log4j具有-log4j.ignoreTCL选项,这使得这成为可能

The Tomcat security manager generally won't let you access webapp classes and resources from libraries in the Tomcat root libraries. Tomcat安全管理器通常不允许您从Tomcat根库中的库访问webapp类和资源。 This is meant to give separation between the web applications running in a container. 这是为了在容器中运行的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. 您应该可以通过更新安全策略来解决这个问题,但通常最好不要将您的lib放入Tomcat容器中,我假设您正在这样做。

I'm expanding Olivier comment as a response (thank you for the lead). 我正在扩大奥利维尔的评论作为回应(谢谢你的领导)。

The problem seems to be the leading slash (/) in the resource path. 问题似乎是资源路径中的前导斜杠(/)。

In Tomcat 8 the WebAppClassloader correctly resolves the path with and without the leading slash. Tomcat 8中 ,WebAppClassloader正确地解析了带有和不带前导斜杠的路径。 Both .getResourceAsStream("/org/pakopa/app/config.properties"); 两个.getResourceAsStream("/org/pakopa/app/config.properties"); and .getResourceAsStream("org/pakopa/app/config.properties"); .getResourceAsStream("org/pakopa/app/config.properties"); returns an InputStream. 返回一个InputStream。

In Tomcat 7 (And I assume previous versions too) .getResourceAsStream("/org/pakopa/app/config.properties"); Tomcat 7中 (我也假设以前的版本) .getResourceAsStream("/org/pakopa/app/config.properties"); is not resolved and returns null but .getResourceAsStream("org/pakopa/app/config.properties"); 没有解析并返回null但是.getResourceAsStream("org/pakopa/app/config.properties"); is correctly resolved. 正确解决了。

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

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