Tomcat:热部署新的JAR包

16

您能在Tomcat 5上热部署JAR文件吗?目的是避免重启Tomcat但仍能够通过反射从新添加的JAR中加载某些类。 是否可以实现?如何实现?对于生产系统是否不可取? 谢谢

编辑: 我的场景需要添加未知名称的新JAR文件。服务器是否可以“监视”JAR目录而不是特定的JAR文件?

2个回答

17

Tomcat没有提供重新加载单个JAR文件的机制。但是,整个上下文可以重新加载。

您只需要在context.xml中告诉Tomcat监视您的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();
        ...
   }

对于 LogFactory.release() 的调用,我给予 +1。虽然我不使用 Apache Commons Logging,但像这样的代码增加了应用程序的信心。更多信息请参见 http://wiki.apache.org/jakarta-commons/Logging/UndeployMemoryLeak。 - Vineet Reynolds

10

是的,这是可能的。前提是开启了自动部署功能,并使用了Tomcat提供的一些技巧:自动应用部署

  1. 如果WAR文件没有对应的目录,它将被自动展开和部署。
  2. 更改WEB-INF\web.xml将导致应用程序重新加载。
  3. 更新已展开的WAR文件将导致重新部署。
  4. 更改XML配置文件应该会导致重新部署。

当然,这在生产系统中是不建议的。这并非因为此功能有误,而是应用程序可能编码不当,未能在卸载时清理资源或卸载类。这将导致某些类仍留存在内存中。当重新部署较新版本的应用程序时,由于旧版本的类仍存在,您将遇到含糊不清的错误。编写不良的单例通常是此问题的最大原因。

为了避免类似问题,我按照以下步骤操作:卸载应用程序,关闭Tomcat,验证Tomcat文件系统目录的“健康状况”,删除任何残留资源,重新启动Tomcat实例并重新部署应用程序。这可能看起来有点麻烦,但我已经吃过亏了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接