SpringBoot 3.1.3配置Log4j2启动报java.lang.StackOverflowError求助
SpringBoot 部署TomEE9配置Log4j2启动报StackOverflowError的原因
问题背景
按照Spring Boot 1.2.9快照版文档中配置Log4j2的指引,将SpringBoot Web应用部署到TomEE 9服务器并使用Log4j2作为日志框架,启动时遭遇java.lang.StackOverflowError失败。
错误栈信息
java.lang.StackOverflowError at org.apache.logging.log4j.jul.Log4jBridgeHandler.getLog4jLogger(Log4jBridgeHandler.java:229) at org.apache.logging.log4j.jul.Log4jBridgeHandler.publish(Log4jBridgeHandler.java:194) at java.logging/java.util.logging.Logger.log(Logger.java:980) at java.logging/java.util.logging.Logger.doLog(Logger.java:1007) at java.logging/java.util.logging.Logger.logp(Logger.java:1173) at org.apache.tomee.jul.formatter.log.JULLogger.log(JULLogger.java:174) at org.apache.tomee.jul.formatter.log.JULLogger.debug(JULLogger.java:102) at org.apache.tomee.jul.formatter.log.TomEELog.debug(TomEELog.java:124) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1291) at org.apache.tomee.catalina.TomEEWebappClassLoader.loadClass(TomEEWebappClassLoader.java:209) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1257) at org.apache.logging.log4j.jul.Log4jBridgeHandler.getLog4jLogger(Log4jBridgeHandler.java:229) at org.apache.logging.log4j.jul.Log4jBridgeHandler.publish(Log4jBridgeHandler.java:194) at java.logging/java.util.logging.Logger.log(Logger.java:980) at java.logging/java.util.logging.Logger.doLog(Logger.java:1007) at java.logging/java.util.logging.Logger.logp(Logger.java:1173) at org.apache.tomee.jul.formatter.log.JULLogger.log(JULLogger.java:174) at org.apache.tomee.jul.formatter.log.JULLogger.debug(JULLogger.java:102) at org.apache.tomee.jul.formatter.log.TomEELog.debug(TomEELog.java:124) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1291) at org.apache.tomee.catalina.TomEEWebappClassLoader.loadClass(TomEEWebappClassLoader.java:209) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1257) . . .
核心原因:日志框架桥接循环调用
从错误栈的循环调用链可以明确问题根源:
- TomEE的Web应用类加载器加载Log4j2相关类时,输出debug级别的类加载日志
- 该日志被TomEE自带的
TomEELog转发到其JULLogger实现 - JUL(java.util.logging)的日志处理器被配置为
Log4jBridgeHandler,将JUL日志桥接到Log4j2 Log4jBridgeHandler处理日志时需要加载Log4j2的Logger类,再次触发Web应用类加载器的类加载操作- 类加载操作又会输出debug日志,重复上述流程,最终导致栈溢出
本质是Log4j2与TomEE自带的JUL日志框架形成了双向桥接循环,加上类加载过程中debug日志的触发点,引发无限递归。
解决建议
- 调整日志级别:将TomEE类加载相关日志的级别从
debug改为info或更高,避免类加载过程中输出日志触发循环,比如修改TomEE的logging.properties配置org.apache.catalina.loader.level=INFO。 - 禁用双向桥接:仅保留单向日志桥接,比如只将JUL日志桥接到Log4j2,禁止Log4j2日志反向流入JUL。可以移除项目中的
log4j-jul依赖,或在Log4j2配置中关闭JUL桥接逻辑。 - 隔离日志类加载:将Log4j2的核心Jar包放入TomEE的系统类加载路径(如
TomEE_HOME/lib目录),而非Web应用的WEB-INF/lib,避免Web应用类加载器加载Log4j类时触发日志循环。 - 修正Spring Boot依赖:确保项目中正确排除默认的
spring-boot-starter-logging依赖,仅引入spring-boot-starter-log4j2,避免依赖冲突导致的日志桥接异常。
内容的提问来源于stack exchange,提问作者HockChai Lim
相关产品推荐
相关产品推荐

