2010-04-16 67 views
12

我有一个Web应用程序,它使用驻留在TOMCAT_HOME/common/lib中的库。这个库查找一个特性在classpath的根目录文件(在一个名为ApplicationConfig类):getResourceAsStream不加载webapp中的资源

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

我的Tomcat Web应用程序包含此属性文件。它在WEB-INF/classes中,这是类路径的根?然而,在运行时,当它试图加载属性文件时,它会抛出一个异常,因为它找不到它(getResourceAsStream返回null)。

如果我的应用程序是一个简单的独立Java应用程序,一切正常。 Tomcat是否会导致getResourceAsStream方法的行为不同?我知道那里有很多类似的问题,但不幸的是他们都没有帮助。谢谢。

回答

22

尝试用Thread.currentThread().getContextClassLoader().getResourceAsStream("/hv-application.properties")代替。

+0

谢谢binil。这是有效的,但我宁愿不必对库进行任何更改。如果找不到其他解决方案,将标记为答案。 – Michael 2010-04-16 14:49:13

+3

奇怪的是,在Tomcat 5.5下使用Win XP和JDK 1.5.08,我能够在不使用前导“/”的情况下加载资源文件。实际上,当预先加入“/”时,我遇到了问题。 – Olivier 2011-01-03 22:52:15

1

Tomcat安全管理器通常不会让您从Tomcat根库中的库访问webapp类和资源。这是为了让运行在容器中的Web应用程序分离。

您应该能够通过更新安全策略来解决此问题,但通常最好不要将您的库放到Tomcat容器中,我认为您正在执行该容器。

+1

这个问题很清楚地表明资源位于WEB-INF/classes目录中... – Pointy 2010-04-16 13:54:08

+0

@stevedbrown,OP表示该文件与WAR一起打包在WEB-INF/classes中。 – 2010-04-16 13:54:30

+0

你读过第一句话了吗? “我有一个Web应用程序,它使用驻留在TOMCAT_HOME/common/lib中的库。该库在类路径的根目录(在名为ApplicationConfig的类中)中查找属性文件:” – stevedbrown 2010-04-16 14:14:00

2

看起来这可能与Tomcat类加载器的工作方式有关。如果某个类加载器(webapp类加载器中的配置文件)在另一个类中使用(common/lib中的jar),结果可能会让人头疼。

这个document解释了Tomcat如何委托给类加载器。如果可能,可以尝试以下方法之一:

  1. 将common/lib中的jar文件移动到您的Web应用程序(WEB-INF/lib)中。我知道这并非总是可能,但有时jar(例如log4j)可以在类加载器(*)中和平共存。
  2. 将您的配置文件移到常用/类中。这实际上是相同的事情(将配置项放入与需要它的jar相同的类加载器中)。再说一次,这并不理想,但如果你能控制自己的环境,那就行了。

无论哪种方式,在不同的类加载器中有资源可能是一种痛苦。我希望这有帮助。

(*)的log4j有-log4j.ignoreTCL选项虽然

+0

感谢Andy,我尝试将我的配置文件移动到common/classes中,但它不起作用。我的webapp是使用这个库的唯一web应用程序,因此我可能会将它移动到WEB-INF/lib中(尽管会有些痛苦,因为我必须修改我的Maven pom以使它包含JAR)。 – Michael 2010-04-16 14:56:54

+0

最好把所有的罐子放在你的webapp里。大多数情况下,这是可能的,但有些情况下将事物移动到common/lib中(例如,如果您正在创建一个旨在跨服务器可用的资源)。 – 2010-04-16 16:18:07

0

我扩大Olivier comment作为响应,这使得这一切成为可能(谢谢你的铅)。

该问题似乎是资源路径中的前导斜杠(/)。

Tomcat 8 WebAppClassloader正确地解析了带和不带前导斜杠的路径。 .getResourceAsStream("/org/pakopa/app/config.properties");.getResourceAsStream("org/pakopa/app/config.properties");都返回一个InputStream。

的Tomcat 7(我认为以前的版本太).getResourceAsStream("/org/pakopa/app/config.properties");没有得到解决,并返回null.getResourceAsStream("org/pakopa/app/config.properties");正确解决。