【发布时间】:2010-11-26 07:18:12
【问题描述】:
你能在 Tomcat 5 上热部署 JAR 文件吗?这个想法是避免重新启动 Tomcat 并且仍然能够(通过反射)从新添加的 JAR 加载某些类。 可以做到吗?如何?对于生产系统是否不可取? 谢谢
编辑:我的方案需要添加事先不知道名称的新 JAR 文件。服务器可以“监视”一个 JAR 目录而不是特定 JAR 吗?
【问题讨论】:
你能在 Tomcat 5 上热部署 JAR 文件吗?这个想法是避免重新启动 Tomcat 并且仍然能够(通过反射)从新添加的 JAR 加载某些类。 可以做到吗?如何?对于生产系统是否不可取? 谢谢
编辑:我的方案需要添加事先不知道名称的新 JAR 文件。服务器可以“监视”一个 JAR 目录而不是特定 JAR 吗?
【问题讨论】:
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();
...
}
【讨论】:
是的,这是可能的。 A few tricks from the Tomcat stable,假设开启了自动部署:
当然,这对于生产系统是不可取的。并不是说此功能有问题,而是应用程序可能编码不当,无法清理资源或在取消部署时卸载类。这将导致某些类保留在内存中。当重新部署较新版本的应用程序时,由于存在较旧版本的类,您将遇到模糊错误。写得不好的单例通常是造成这个问题的最大原因。
为了避免任何类似问题,我遵循的协议是取消部署应用程序,关闭 Tomcat,验证 Tomcat 文件系统目录的“健全性”,删除任何遗留的资源,重新启动 Tomcat 实例并重新部署应用程序.它看起来确实有点沉重,但我已经被烧得够呛了。
【讨论】: