2010-04-16 69 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");正確解決。