2009-09-07 108 views
12

您可以在Tomcat 5上熱部署JAR文件嗎?這個想法是爲了避免重新啓動Tomcat,並且仍然能夠從新添加的JAR中加載(通過反射)一些類。 可以這樣做嗎?怎麼樣?生產系統是不可取的嗎? 謝謝Tomcat:熱部署新罐子

編輯:我的方案需要添加新的名稱未知的JAR文件。服務器可以「監視」JAR的目錄而不是特定的JAR嗎?

回答

9

是的,這是可能的。 A few tricks from the Tomcat stable,假設自動部署被打開:

  1. 如果WAR文件中沒有相應的目錄時,它會自動膨脹和展開。
  2. 對WEB-INF \ web.xml的更改將導致應用程序重新加載。
  3. 更新爆炸WAR文件將導致重新部署
  4. 更改的XML配置文件都應該引起重新部署

當然,這是不可取的生產系統。並不是說這個功能有問題,但是應用程序可能編寫得很糟糕,不能清理資源或在取消部署時卸載類。這將導致某些類保留在內存中。當新版本的應用程序重新部署時,由於存在較舊版本的類,您將會遇到模糊的錯誤。寫得不好的單身人士往往是這個問題的最大原因。

爲了避免任何類似的問題,我遵循的協議是取消部署應用程序,取消Tomcat,驗證Tomcat文件系統目錄的'完整性',刪除留下的所有資源,重新啓動Tomcat實例並重新部署應用。它看起來有點笨重,但我已經燒得夠嗆了。

11

Tomcat不提供任何機制來重新加載單個JAR。但是,整個上下文可以重新加載。

你只需要告訴Tomcat來觀看在context.xml中的JAR,這樣,

<?xml version="1.0" encoding="UTF-8"?> 
<Context override="true" swallowOutput="true" useNaming="false"> 
    <WatchedResource>WEB-INF/web.xml</WatchedResource> 
    <WatchedResource>WEB-INF/lib/your.jar</WatchedResource> 
    <Manager pathname=""/> 
</Context> 

我們這樣做是對生產。 Tomcat曾經有一些內存泄漏,但是我們沒有發現Tomcat 5.5或更高版本的任何問題。

不知道是否仍然有必要。我們必須進行以下調用以避免熱部署期間內存泄漏。

public void contextDestroyed(ServletContextEvent sce) { 
     // To fix the known memory leaks during re-deploy 
     ClassLoader contextClassLoader = 
      Thread.currentThread().getContextClassLoader(); 
     LogFactory.release(contextClassLoader); 

     java.beans.Introspector.flushCaches(); 
     ... 
    } 
+0

對於LogFactory.release()調用+1。儘管我沒有使用Apache Commons Logging,但它是這樣的代碼,可以增強應用程序的信心。更多信息@http://wiki.apache.org/jakarta-commons/Logging/UndeployMemoryLeak – 2009-09-07 18:54:54

+0

謝謝你們......請參閱OP中的編輯。 – 2009-09-08 13:16:20