此Web应用程序实例已停止。无法加载

2023-05-16

1.1 现象

关闭tomcat时,报无法加载类的错误。

非法访问:此Web应用程序实例已停止。无法加载[io.netty.util.concurrent.DefaultPromise$1]java.lang.NoClassDefFoundError

1.2 线程关闭

导致无法加载加载的原因就是tomcat已经关闭了类加载器,但是部分线程还在运行。

简单理解就是tomcat关闭的线程和用户其他线程没有串行执行。

比如:

把springboot+netty项目发布到外置tomcat,netty的关闭就是异步提交到线程

public class StartEventListener implements ApplicationListener<ContextClosedEvent> {
    @Override
    public void onApplicationEvent(ContextClosedEvent event) {
        System.out.println("通过事件关闭"); //先event 后DisposableBean
        bossGroup.shutdownGracefully();
    }
}
public class StartEventListener implements DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("通过destroy关闭");
        bossGroup.shutdownGracefully();
    }
}

关闭tomcat发现报错:

23-Jun-2021 14:24:20.687 严重 [main] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@23e84203]) and a value of type [io.netty.util.internal.InternalThreadLocalMap] (value [io.netty.util.internal.InternalThreadLocalMap@19932c16]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
23-Jun-2021 14:24:20.689 信息 [main] org.apache.coyote.AbstractProtocol.stop 正在停止ProtocolHandler ["http-nio-8080"]
23-Jun-2021 14:24:20.691 信息 [main] org.apache.coyote.AbstractProtocol.stop 正在停止ProtocolHandler ["ajp-nio-8009"]
23-Jun-2021 14:24:20.692 信息 [main] org.apache.coyote.AbstractProtocol.destroy 正在摧毁协议处理器 ["http-nio-8080"]
23-Jun-2021 14:24:20.692 信息 [main] org.apache.coyote.AbstractProtocol.destroy 正在摧毁协议处理器 ["ajp-nio-8009"]
23-Jun-2021 14:24:22.691 信息 [nioEventLoopGroup-3-1] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading 非法访问:此Web应用程序实例已停止。无法加载[io.netty.util.concurrent.GlobalEventExecutor$2]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。
	java.lang.IllegalStateException: 非法访问:此Web应用程序实例已停止。无法加载[io.netty.util.concurrent.GlobalEventExecutor$2]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。
		at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1385)
		at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForClassLoading(WebappClassLoaderBase.java:1373)
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1226)
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1188)
		at io.netty.util.concurrent.GlobalEventExecutor.startThread(GlobalEventExecutor.java:220)
		at io.netty.util.concurrent.GlobalEventExecutor.execute(GlobalEventExecutor.java:208)
		at io.netty.util.concurrent.DefaultPromise.safeExecute(DefaultPromise.java:842)
		at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:499)
		at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:616)
		at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:605)
		at io.netty.util.concurrent.DefaultPromise.setSuccess(DefaultPromise.java:96)
		at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:1051)
		at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
		at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
		at java.lang.Thread.run(Thread.java:748)

还有找不到类的错误(类实际存在)

Exception in thread "nioEventLoopGroup-3-1" java.lang.NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy
	at ch.qos.logback.classic.spi.LoggingEvent.<init>(LoggingEvent.java:119)
	at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:419)
	at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
	at ch.qos.logback.classic.Logger.log(Logger.java:765)
	at io.netty.util.internal.logging.LocationAwareSlf4JLogger.log(LocationAwareSlf4JLogger.java:46)
	at io.netty.util.internal.logging.LocationAwareSlf4JLogger.error(LocationAwareSlf4JLogger.java:249)
	at io.netty.util.concurrent.DefaultPromise.safeExecute(DefaultPromise.java:844)
	at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:499)
	at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:616)
	at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:605)
	at io.netty.util.concurrent.DefaultPromise.setSuccess(DefaultPromise.java:96)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:1051)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:748)

1.3 springboot外置tomcat分析

//通常我们要实现 SpringBootServletInitializer
public class ServletInitializer extends SpringBootServletInitializer {

    private static final Logger LOGGER = LoggerFactory.getLogger(ServletInitializer.class);
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SpringbootApplication.class);
    }

}
//而SpringBootServletInitializer 启动过程会注册ServletContextListener实现类
public abstract class SpringBootServletInitializer implements WebApplicationInitializer {
@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		// Logger initialization is deferred in case an ordered
		// LogServletContextInitializer is being used
		this.logger = LogFactory.getLog(getClass());
		WebApplicationContext rootApplicationContext = createRootApplicationContext(servletContext);
		if (rootApplicationContext != null) {
			servletContext.addListener(new SpringBootContextLoaderListener
                                       (rootApplicationContext, servletContext));
		}
		
	}
}
//ServletContextListener实现类SpringBootContextLoaderListener中 关闭容器
    public void contextDestroyed(ServletContextEvent event) {
        this.closeWebApplicationContext(event.getServletContext());
        ContextCleanupListener.cleanupAttributes(event.getServletContext());
    }

/*
通过以上分析可知,关闭tocmat会先发送ContextClosedEvent然后调用DisposableBean
我们在这两个位置来释放资源即可,注意要串行。

*/

1.4 异常原因

原因:关闭tomcat时,netty是异步执行,导致tomcat关闭了类加载器,而netty仍然在执行(需要加载类)。
解决:将netty关闭串行话,保证netty先关闭然后tomcat继续往下走。
     
总结:异步线程关闭在外置tomcat中建议都做串行处理。

1.5 正确关闭

1、如果使用springboot内置tomcat,也是多线程为什么不出错,答:springboot已经做串行处理
2、针对本文的错误只需 
  将bossGroup.shutdownGracefully(); 修改为 bossGroup.shutdownGracefully().sync();串行执行。
  

1.6 springboot内外置tomcat

springboot内置tomcat启动方式,进程是springboot,
	所以关闭逻辑入口是Runtime.getRuntime().addShutdownHook
	特点:启动入口是@SpringBootApplication注解的main类且SpringApplication.run启动

springboot外置tomcat方式,进程是tomcat
	tomcat提供了ServletContextListener入口,springboot实现此接口进入spring容器关闭
	特点:需要手动实现SpringBootServletInitializer
    比如public class ServletInitializer extends SpringBootServletInitializer
    
    
springMVC的核心servlet是FrameworkServlet其实现了 Servlet 的 destroy 方法 ,
	destroy内部调用applicationContext.close()进入容器关闭生命周期阶段
    

补充:

1、 SpringBoot 模式的优雅关闭

	private void refreshContext(ConfigurableApplicationContext context) {
		if (this.registerShutdownHook) {
			try {
				context.registerShutdownHook();
			}
			catch (AccessControlException ex) {
				// Not allowed in some environments.
			}
		}
		refresh((ApplicationContext) context);
	}
/*
springboot采用外置tomcat启动时会调用:
	application.setRegisterShutdownHook(false);
	从而不走 Runtime.getRuntime().addShutdownHook方式,走servlet周期
springboot采用内置tomcat启动时:	
	registerShutdownHook默认是true,所以采用addShutdownHook方式 
印证了1.5

而https://www.jianshu.com/p/69b704279066 中
 3 SpringBoot 模式的优雅关闭 一节说,tomcat 的关闭和 springboot 的关闭是并行的
 	是【错误的】
*/

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

此Web应用程序实例已停止。无法加载 的相关文章

  • DDGCN: A Dynamic Directed Graph Convolutional Network for Action Recognition

    Introduction 作者认为解决如下两个问题能有效增强GCN在动作识别中的能力 xff1a 1 在人类骨骼的不同部位中有着时空关联性 xff0c 但这些关联性是动态的 xff0c 而且在时空域中不同的动作关联性也是不同的 标椎卷积操作
  • 2023最新版动力节点MybatisPlus实战教程——拓展篇

    5 拓展篇 5 1 逻辑删除 前面我们完成了基本的增删改查操作 xff0c 但是对于删除操作来说 xff0c 我们思考一个问题 xff0c 在实际开发中我们真的会将数据完成从数据库中删除掉么 xff1f 当然是不会的 xff0c 这里我们举
  • 计算机的存储器层次结构以及一二三级缓存的区别

    hibernate 一级缓存和二级缓存的区别 xff1a 主要的不同是它们的作用范围不同 一级缓存是session级别的 也就是只有在同一个session里缓存才起作用 xff0c 当这个session关闭后这个缓存就不存在了 而二级缓存是
  • QWebEngine登录网页并获取数据

    利用QWebEngine登录需要账号密码的网页并获取想要的数据 xff0c 以某游戏网站为例 xff0c 此网站每隔一段时间会更新某些数据 1 设置QWebEngineView的url QWebEngineView setUrl 在QWeb
  • PyCharm 提示 unresolved reference

    PyCharm 外部模块导入提示 unresolved reference 解决方法是把文件夹设置为根目录 1 在项目上单击右键 gt Mark Directory as gt Sources Root 2 再次点击 xff0c 红色警告消
  • python 安装twisted库时提示缺少VC++ 14.0 (解决方案)

    说明 xff1a 出现这种问题 xff0c 不需要去安装VC 43 43 14 0 xff0c 只需要去python库上下载相应的包安装即可 1 在python库中下载twisted相应的包 xff08 whl文件 xff09 网址 xff
  • 虚拟机中ubuntu下make menuconfig命令缺少ncurses解决方法

    在台式机上按着教程弄编译内核什么的 xff0c 发现同样是RHEL5 xff0c 我的make menuconfig就缺失ncurses 然后我装的RHEL5还连不上网了 xff0c 那怎么办 xff0c 没法传东西 xff0c vmtoo
  • HDU 1215 七夕节(约数之和)

    七夕节 Time Limit 2000 1000 MS Java Others Memory Limit 65536 32768 K Java Others Total Submission s 39837 Accepted Submiss
  • 为什么无穷大总是0x3f3f3f3f?

    转自 http aikilis tk 如果问题中各数据的范围明确 xff0c 那么无穷大的设定不是问题 xff0c 在不明确的情况下 xff0c 很多程序 员都取0x7fffffff作为无穷大 xff0c 因为这是32 bit int的最大
  • CSU 1333 & Uva 12661 Funny Car Racing【最短路变形+spfa算法,链式前向星建图】

    Funny Car Racing Memory Limit 131072KB64bit IO Format lld amp llu Status Description There is a funny car racing in a ci
  • 根据Oracle数据库scott模式下的scott.emp表和dept表,完成下列操作.

    题目要求 xff1a 根据Oracle数据库scott模式下的emp表和dept表 xff0c 完成下列操作 将scott用户解锁 xff1a alter user scott account unlock scott的初始密码是tiger
  • 通过CSS选择器查找元素

    通过CSS选择器定位元素 以Google主页的搜索按钮为例 xff0c 其中HTML代码如下 xff1a lt input value 61 34 Google 搜索 34 jsaction 61 34 sf chk 34 name 61
  • STL-set (集合)之删除元素

    set概述 和vector list不同 xff0c set map都是关联式容器 set内部是基于红黑树实现的 插入和删除操作效率较高 xff0c 因为只需要修改相关指针而不用进行数据的移动 在进行数据删除操作后 xff0c 迭代器会不会
  • 经典算法之一:快速排序

    快速排序由于排序效率在同为O N logN 的几种排序方法中效率较高 xff0c 因此经常被采用 xff0c 再加上快速排序思想 分治法也确实实用 xff0c 因此很多软件公司的笔试面试 xff0c 包括像腾讯 xff0c 微软等知名IT公
  • 矩阵乘法测试

    对于时间的函数 gettimeofday 函数使用方法 xff1a http blog csdn net hurmishine article details 60326345 矩阵乘法测试 xff1a 代码 xff1a 1 为了试验简单
  • 全网最!详!细!Tarjan算法讲解。

    Tarjan算法讲解的博客网上找到三篇比较好的 现在都转载了 个人只研究了第一篇 正如博主所说 讲的标比较详细 清晰 剩下两篇也可以看一下 卿学姐视频讲解 https www bilibili com video av7330663 以下内
  • MFC计算机图形学(1)

    这学期上了计算机图形学 xff0c 用MFC来绘制简单的图形 下面就简单介绍一下用cv 43 43 来绘制图形 VC 43 43 安装 VC 43 43 我基本不用的 xff0c 平时写C C 43 43 的代码都用Code Blocks
  • MFC计算机图形学(2)

    这里呢 xff0c 先把上一讲的联系讲一下 一般人都用是一个一个的去画 xff0c 但是那样好麻烦 xff0c 计算机的有点就是容易处理重复的事情 xff0c 那就定义成一个画正方形函数吧 xff0c 每次调用就可以了 怎么自定义函数呢 x
  • MFC计算机图形学(3)

    之前我们已经可以画出直线和曲线了 但是算法虽容易理解 xff0c 但是复杂度高 xff0c 今天就介绍比较流行的DDA画线法 xff0c 还有 xff0c 对鼠标进行事件有所响应 xff0c 即 xff0c 在画板上 xff0c 鼠标左键单
  • CentOS7手工安装远程图形化程序

    CentOS7手工安装远程图形化程序 xff08 X11Forwarding xff09 用途 tomcat服务部署在linux服务器 xff0c 需要使用jconsle或jvisualvm检查web服务状态 xff1b 但是使用xterm

随机推荐

  • aosp/ota/incremental update package/安卓 7aosp代码增量升级包

    make otapackage out target product aosp aosp ota eng lake zip 61 61 61 gt full update NOT used for incremental package B
  • Matplotlib系列(七):动画

    Matplotlib系列目录 文章目录 一 简介二 思维导图三 Matplotlib动画及图形修改操作1 手写代码更新图形实现动画2 animation模块动画2 1 Animation类简介2 2 FuncAnimation动画2 3 A
  • 01-Docker实战,搭建NodeJs环境

    目的 实现简单的docker的nodejs容器 xff0c 使用Dockerfile构建我们的使用nodejs开发的系统 技术栈 DockerNodejsExpressLinux step1 下拉nodejs基础容器 node 本次我需要使
  • 【Cocos2d-X-2.1.4游戏引擎】发布第一个游戏

    有一段时间没更新博客了 xff0c 最近一直在写一个小游戏 xff0c 游戏在今天终于搞好了 xff0c 又可以开始写写博客 xff0c 打打dota的悠闲的日子了哈 看了十几天cocos2d x后 xff0c 也依照官网的例子写了个打飞机
  • 游戏升级之路

    七十一雾央原创 转载请注明 http blog csdn net hust xy 楼主学习编程有两年了 xff0c 决定向游戏发展大概就是半年前了 xff0c 在这里总结一下游戏方面的学习经历过 xff0c 给初学的朋友们参考下 xff0c
  • vs2017下linux远程调试经验

    调了半天 xff0c 终于进入gdb断点调试了 xff0c 下面分享下经验 xff1a 1 vs2017建立工程 xff0c 出现gdb server找不到 xff0c 解决方法 xff1a http blog csdn net hutia
  • Android Studio 3.6新功能ViewBinding解析

    Android Studio使用技巧 看这一篇就够了 Google官方在2020年3月份发布了Android Studio3 6的版本 xff0c 此版本增加了很多新的功能 xff0c 其中一大亮点功能就是ViewBinding ViewB
  • VBoxManage 命令详解

    查看当前虚拟机 VBxoManage list vms 查看当前正在运行的虚拟机 VBoxManage list runningvms 启动虚拟机 VBoxManage startvm 虚拟机名 无前端图形界面方式启动虚拟机 VBoxMan
  • [Errno 256] No more mirrors to try.解决过程

    今天在Linux服务器上安装rdesktop安装包的时候遇到该报错 xff0c 如图所示 xff1a df h查看挂载盘信息 xff0c 发现光驱未挂载 我设置的挂载光驱路径为 media cdrom 解决过程 xff1a 1 挂载光驱 m
  • c# 简单调用rabbitmq

    如果小伙伴们还没有安装rabbitmq xff0c 可以参考下面链接 https www cnblogs com kiba p 11703073 html 如果想要快速获取整个rabbitmq安装包 xff0c 就关注本人公众号 墨水直达
  • 如何学习一门编程语言,从入门到不放弃!

    在学习前 xff0c 如果能把以下几个方面的问题弄清楚 xff0c 就能够比较顺利和高效的学习 xff0c 拿到你所想要的目标 而不是从入门到放弃 一 方向和目标 首先要确定为什么要学习计算机编程语言 xff0c 为考试 xff1f 为工作
  • 一年精通,三年熟悉,五年了解,十年用过!C++真的这么难吗?

    C 43 43 有句俗话说 xff1a 一年精通 三年熟悉 五年了解 十年用过 如果可以把C 43 43 程序员分层的话 xff0c 看看你在第几层 xff1f 第0层 掌握基本的C 43 43 语法 xff0c 会写一些基本的if els
  • 2023年最新manim系列教程【持续更新中】

    2023年最新Manim系列教程 将持续更新 xff1a 教程更新过程中 xff0c 依旧会对于已发布内容进行更新维护 xff0c 包括但不限于纠错 xff0c 将官网公布的过时功能更新到新版等 个人博客官网 xff1a https mar
  • eclipse代码补齐快捷键失效问题

    1 xff1a 在Window preference general下面的keys中 xff0c 把content asist这个改成alt 43 2 xff1a 在下面 xff0c 有一个when xff0c 选择editing text
  • Ubuntu 界面卡死的办法

  • idea toggle offline mode

    toggle offline mode 切换脱机模式 当点击这个按钮 xff0c 就会进入脱机模式 当您切换到脱机模式时 xff0c maven必须使用本地的资源 xff0c 比如依赖 xff08 只会本地仓库找 xff0c 不会网上去下载
  • 《机器学习》课后习题3.5 编辑实现线性判别分析,并给出西瓜数据集 3.0α 上的结果.

    参考了han同学的答案 xff0c 西瓜数据集也可在han同学的github上下载 3 5 编辑实现线性判别分析 xff0c 并给出西瓜数据集 3 0 上的结果 span class token keyword import span nu
  • Centos 8下安装jdk1.8

    安装环境 xff1a Centos 8 JDK版本 xff1a 1 8 用户名 xff1a huwei JDK1 8压缩包链接 xff1a https pan baidu com s 15DfvlIKRl1G4fk5rFNigQg 提取码
  • java同步获取异步任务结果JavaPromise

    同步获取异步任务结果 思路 xff1a 首先从jdk提供的框架和代码入手 xff0c 然后再自己定义一个 xff0c 原创qq作者 855189478 1 CountDownLatch 使用同步框架可以实现同步 xff0c 但是不能获取到异
  • 此Web应用程序实例已停止。无法加载

    1 1 现象 关闭tomcat时 xff0c 报无法加载类的错误 非法访问 xff1a 此Web应用程序实例已停止 无法加载 io netty util concurrent DefaultPromise 1 java lang NoCla