如何在tomcat中彻底取消部署Spring Boot / Jersey战争

时间:2017-10-23 06:37:48

标签: java spring tomcat jersey

考虑一个非常简单的Spring Boot / Jersey应用程序设置:

  • 使用Initializr生成一个全新的Spring Boot应用程序并选择Jersey依赖项(在我的情况下,我更喜欢Gradle设置)。
  • 添加简单的控制器和配置类:

JerseyConfig.java

std::vector

TestController.java

package com.example.unload;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JerseyConfig extends ResourceConfig {
    JerseyConfig() { register(TestController.class); }
}
  • 运行package com.example.unload; import org.springframework.stereotype.Component; import javax.ws.rs.GET; import javax.ws.rs.Path; @Component @Path("test") public class TestController { @GET public String test() { return "test"; } } 任务并将WAR部署到Tomcat(在我的情况下为8.5)。

每当我想取消部署(例如重新部署)WAR时,我都会收到以下错误消息

war

罪魁祸首是lib目录中的jersey-server-2.25.1.jar,显然某些类加载器必须有一个引用。我也无法手动删除该文件,因为Java会对其进行锁定。

有趣的是,在手动执行GC运行(外部通过jvisualvm)后,我能够删除jersey-server.jar。 因此,我怀疑流未正确关闭(但在最终确定期间会关闭)。

当然,在生产环境中不能手动执行GC运行。 我尝试在Oct 23, 2017 8:13:11 AM org.apache.catalina.startup.ExpandWar deleteDir FATAL: […\apache-tomcat-8.5.20\webapps\unload-0.0.1-SNAPSHOT\WEB-INF\lib] could not be completely deleted. The presence of the remaining files may cause problems 的{​​{1}}回调中调用System.gc(),但是在仍有实时引用时会调用它。

我也知道contextDestroyed文件中的ServletContextListener选项,但这会在临时目录中创建整个WAR内容的副本,而不会删除它(这可能是一个cron job)。但是,这更像是一种解决方案,而不是一种高效的解决方案。 第三种可能的选择是提取所有Spring,Jersey和相关的依赖项并将其移动到Tomcat的共享antiResourceLocking目录,但我更喜欢捆绑所有必需的依赖项以简化客户的部署。

我还有其他选择,根本原因是什么? 我没有找到任何关于Tomcat,Spring和Jersey的错误的引用。

我可以用Jersey 2.26和jersey-hk2 2.26重现这个问题。

0 个答案:

没有答案