2008-11-25 31 views
2

我們已經舉辦了在Tomcat 6.0.18 Web應用程序,並經歷了以下幾個問題:問題的類加載器在長時間運行的Tomcat進程

有兩個Web應用程序WebApp1和webapp2的,都是同一個系統,但不同的版本。

現在的問題是,當tomcat已經運行了一週或更長的時間,然後有時系統會給出NoClassDefFoundError!我們也遇到了一些奇怪的問題,WebApp1的Class Loader加載了WebApp2 jar中的類! WebApp1中也存在相同的jar,但版本不同。

當我們重新啓動Tomcat時,一切都開始正常工作!我們的JRE是1.5.10

請讓我知道你是否遇到過這樣的問題。

問候, Jatan Porecha

回答

1

我遇到使用Tomcat的類加載器古怪的很多很多味道 - 即使你自己都不執行任何代碼的類加載器,它很容易爲Tomcat本身產生的問題。最常見的問題似乎是反覆卸載並重新加載Web應用程序泄漏類加載器,並最終運行Tomcat內存不足。

我發現版本不匹配的最常見原因是Tomcat確保某些類和jar(Tomcat本身的一部分)在webapp類路徑中的任何其他類之前 - commons-logging似乎是最常見的示例 - 當你不期望的時候,可以加載,卸載類裝載器,或者保持它。

您能否提供一些更多的細節 - 如果jar是來自第三方,那麼以前有人很可能會看到這個問題。如果它是你自己的jar,那麼你在應用程序中是否有你自己的classloader代碼?

0

感謝克里斯的迴應。

該jar已成爲系統的一部分,並具有一些其他進程共享的公共類。

讓我們稱之爲罐子comutils.jar所以情況是一樣的東西,

 
WebApp1 (ver 1) 
    | 
    |- comutils.jar (ver 1) 
     | 
     |- MailSender.class (ver 1) 


WebApp2 (ver 2) 
    | 
    |- comutils.jar (ver 2) 
     | 
     |- MailSender.class (ver 2) 

這MailSender類是單身。

現在有時會發生什麼情況是,每當WebApp1的代碼在使用getInstance方法檢索其實例後調用MailSender的任何方法時,實際調用將轉到MailSender(版本2)而不是版本1!

希望這會給你一些主角。

+0

我認爲這是_far_你就越有可能在WebApp1的類路徑中某處部署comutils.jar額外的版本比它是Tomcat的ClassLoader是突然從外面的類路徑加載類...檢查MailSender.class僅位於一個地方。 – 2008-11-25 19:21:45

1

我還沒有足夠的代表添加評論,所以我不得不張貼另一個答案。 :)

這聽起來像MailSender.class越來越加載到Tomcat,而不是每個單獨的Web應用程序。 WebApp2首先加載並運行,即使它被加載到所有非WebApp2專用的Tomcat中。當WebApp1需要該類時,它已經將其加載到Tomcat父級中,並且不會嘗試將一個私有加載到WebApp1。

我首先建議你檢查一下你的Tomcat,JRE等目錄,看看有沒有某種方式的jar或這些路徑中的類的副本。之後,我會手動從兩個jar文件中刪除這個類,並重新啓動Tomcat或Web應用程序,以查看會發生什麼 - 您會希望它失敗並生成堆棧跟蹤,並且會告訴您您的類首次加載的位置誰試圖加載它。 (例如,從類名中可能會得到一個郵件API,加載到Tomcat JVM中,將類加載到Tomcat中,而不是加載到Web應用程序中)。

1

是否有一個特定的原因,你在同一臺服務器上託管2個完全相同的代碼版本?

擁有2個不同的名稱完全相同的jar包含相同名稱空間中的類,並且具有相同的類名似乎會導致各種問題(其中最重要的是人爲錯誤)。