2010-06-19 66 views
2

如果我有需要在我的webapp和Tomcat之間共享的類(例如,自定義領域和委託人),那麼包含這些類的.jar文件應該放在哪裏?類加載器和與Apache Tomcat共享.jar文件

目前我將.jar放入$ {CATALINA_HOME}/lib中。當從相同類型的類中分配引用時,此結果是一個ClassCastException。這裏有一個例子:

MyCustomPrincipal principal = (MyCustomPrincipal)FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal(); 

上面的方法拋出一個ClassCastException。該方法返回實際的MyCustomPrincipal類型(因爲這是我的自定義領域在執行身份驗證時給Tomcat的東西),顯然,它是由不同的類加載器創建的。我如何解決這個問題,以便Tomcat和我的webapp都可以使用MyCustomPrincipal?

http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html

任何幫助表示讚賞。 Andrew

+0

你的webapp中是否有另一個JAR副本? – 2010-06-19 19:43:42

+0

是的,部署到Tomcat的.war文件包含MyCustomPrincipal.class。 – Andrew 2010-06-19 19:52:16

回答

4

看起來您已經加載了2個副本,一次在tomcat中,一次在您的WEB-INF/lib jar或已部署應用程序的其他類路徑中。

你得到classpath異常的原因在於WAR尋找類的方式。與普通的Java規則相反,戰爭首先在戰爭中尋找類,然後纔將請求傳遞給父類加載器。

一個類的標識依賴於類加載器,並且在一個類加載器中加載的相同類將在另一個類加載器中進行轉換時生成一個classcast異常。

解決方案是確保戰爭不包含容器應該提供的類。如果您使用maven,則可以將這些依賴項標記爲「提供」,如果使用ant,則必須將類路徑列表拆分爲2並針對兩者進行編譯,但僅使用構建戰爭所需的那些。

+0

好的,這是有道理的。如果我理解正確,我需要確保類文件只有一個源。 我正在使用NetBeans,它使用Ant構建.war文件。目前我已經更新了build.xml以將包含我的自定義主體和領域的.jar預部署到$ {CATALINA_HOME}/lib。我可以只更新build.xml並告訴Ant不要在.war中部署MyCustomPrincipal.class? – Andrew 2010-06-19 19:59:26

+0

是的,如果這是唯一的,那麼添加一個排除行。如果它更重複,那麼支付2個列表是值得的。 – 2010-06-19 20:02:48

+0

非常感謝您的幫助。對此,我真的非常感激。 – Andrew 2010-06-19 20:10:48