Java Tomcat:热部署新 jars

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1390487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 11:34:19  来源:igfitidea点击:

Tomcat: hot deploying new jars

javatomcatjar

提问by Germán

Can you hot deploy JAR files on Tomcat 5? The idea is to avoid restarting Tomcat and still be able to load (via reflection) some class from a newly added JAR. Can it be done? How? Is it unadvisable for a production system? Thanks

你可以在Tomcat 5上热部署JAR文件吗?这个想法是为了避免重新启动 Tomcat 并且仍然能够从新添加的 JAR 加载(通过反射)一些类。可以做到吗?如何?对于生产系统来说是不明智的吗?谢谢

Edit: my scenario requires the addition of new JAR files for which the names aren't known in advance. Can the server be "watching" a directory of JARs rather than specific JARs?

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

回答by Vineet Reynolds

Yes, it is possible. A few tricks from the Tomcat stable, assuming that automatic deployment was switched on:

对的,这是可能的。Tomcat stable 的一些技巧,假设开启了自动部署:

  1. If a WAR file does not have a corresponding directory, it will be automatically expanded and deployed.
  2. Changes to WEB-INF\web.xml will cause a reload of the application.
  3. Updates to exploded WAR files will cause a redeployment
  4. Changes to the XML configuration files are supposed to cause a redeployment
  1. 如果一个 WAR 文件没有对应的目录,它会自动展开部署。
  2. 对 WEB-INF\web.xml 的更改将导致应用程序重新加载。
  3. 对分解的 WAR 文件的更新将导致重新部署
  4. 对 XML 配置文件的更改应该会导致重新部署

Of course, this is not advisable for production systems. Not that this feature is faulty, but applications can be poorly coded to not clean up resources or unload classes on undeployment. This will result in certain classes remaining in memory. When the newer version of the application is redeployed, you will encounter vague errors due to the older version of the classes being present. Poorly written singletons, are often the biggest cause of this issue.

当然,这对于生产系统是不可取的。并不是说这个功能有问题,而是应用程序可能编码很差,无法在取消部署时清理资源或卸载类。这将导致某些类保留在内存中。重新部署较新版本的应用程序时,由于存在较旧版本的类,您将遇到模糊错误。写得不好的单身人士往往是这个问题的最大原因。

The protocol that I follow, to avoid any similar issues is to undeploy the application, bring down Tomcat, verify the 'sanity' of the filesystem directories of Tomcat, delete any resources left behind, restart the Tomcat instance and redeploy the application. It does look a little heavy handed, but I've been burnt enough.

为了避免任何类似问题,我遵循的协议是取消部署应用程序,关闭 Tomcat,验证 Tomcat 文件系统目录的“健全性”,删除任何遗留的资源,重新启动 Tomcat 实例并重新部署应用程序。它看起来确实有点笨手笨脚,但我已经被烧得够多了。

回答by ZZ Coder

Tomcat doesn't provide any mechanism to reload a single JAR. However, the whole context can be reloaded.

Tomcat 不提供任何重新加载单个 JAR 的机制。但是,可以重新加载整个上下文。

You just need to tell Tomcat to watch for your JAR in context.xml, like this,

你只需要告诉 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>

We do this on production. Tomcat used to have some memory leaks but we haven't found any issues with Tomcat 5.5 or later.

我们在生产中这样做。Tomcat 曾经有一些内存泄漏,但我们没有发现 Tomcat 5.5 或更高版本的任何问题。

Don't know if it's still necessary. We have to make following calls to avoid memory leak during hot deployment.

不知道还有没有必要。我们必须进行以下调用以避免热部署期间的内存泄漏。

   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();
        ...
   }