我正在尝试使用 log4j appender 将日志发送到 GrayLog2 (log4j2-gelf
)。所以我将我的依赖项添加到我的 pom.xml
配置 log4j2.xml
来配置我的 appender。使用 maven 构建整个东西并将其部署到本地 tomcat,一切正常。
当我尝试关闭 tomcat 时,问题发生了。
如果我不 kill -9 PID
tomcat 和 catalina.out
结束,Tomcat 不会停止:Complete stack trace
引起我注意的是
java.lang.NoClassDefFoundError: io/netty/util/concurrent/DefaultPromise$1
首先我认为我可能有另一个导入 netty 的依赖项会导致此异常。但我找了一段时间,没能找到任何其他的 netty 导入。然后我看到了:
Caused by: java.lang.ClassNotFoundException: Illegal access: this web application instance has been stopped already. Could not load [io.netty.buffer.PoolArena$1]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
这就是我的问题所在。 我的理解是 gelf-appender 使用 Netty 作为与 GrayLog 服务器异步通信的方式。但它本身就是一个服务器。那么 Tomcat 是否有可能在杀死底层 Netty 之前停止父 servlet?哪个会导致这个问题? 我试图找到一些关于 Tomcat 关闭方式的文档,但到目前为止我没有找到任何东西,除此之外我在这个诊断方面可能完全错了......
最佳答案
看起来你的类加载器有问题
Caused by: java.lang.ClassNotFoundException: Illegal access: this web application instance has been stopped already. Could not load [io.netty.buffer.PoolArena$1]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access. at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForClassLoading(WebappClassLoaderBase.java:1342)
WebappClassLoader
在收到关闭信号时停止为传入的加载请求提供服务。您需要在 WebappClassLoader
之外访问 Netty jar。将其放入 $CATALINA_HOME/lib
(参见 Tomcat classloader howto, section Common)。要找到正确的 jar,请为您的 webapp 运行 mvn dependency:tree
(如果您使用 maven)
关于Java Tomcat,底层 Netty 线程没有停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40930844/