You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Tomcat 8升级到Tomcat 10后Log4j异常问题求助

问题解决方案

针对问题1:StackOverflowError 循环调用异常

这个异常是类加载器与日志初始化的循环依赖导致的:WebappClassLoader加载Spring Boot的Log4j2LoggingSystem时,触发JUL日志检查,而JUL又调用WebappClassLoader的类加载逻辑,形成死循环。

解决步骤:

  • 废弃Tomcat/lib下自定义jars文件夹的方式,Tomcat10的类加载机制对容器级依赖的管理更严格,不建议自定义目录扩展类路径。
  • 将所有Log4j2相关jar包直接放置到%CATALINA_HOME/lib目录下,后续通过JVM参数统一配置日志桥接。

针对问题2:ClassNotFoundException(log4j-jul类找不到)

报错的核心是JUL的LogManager初始化早于Tomcat的Catalina类加载器启动:JDK17中,java.util.logging.LogManager是由启动类加载器(Bootstrap/AppClassLoader)初始化的,而%CATALINA_HOME/lib下的jar是由Tomcat的Catalina类加载器加载的,启动类加载器无法访问这些类。

解决步骤:

  1. 将log4j-jul-2.20.0.jar复制到JDK的扩展目录:$JAVA_HOME/jmods(JDK17推荐)或者$JAVA_HOME/lib/ext(兼容方式)。
  2. 或者在Tomcat的启动脚本(catalina.bat/catalina.sh)中,添加JVM参数将Log4j相关jar加入启动类路径:
    set JAVA_OPTS=%JAVA_OPTS% -cp "%CATALINA_HOME/lib/log4j-api-2.20.0.jar;%CATALINA_HOME/lib/log4j-jul-2.20.0.jar"
    
    注意:需要把所有依赖的Log4j核心jar都包含进去,避免后续依赖缺失。
  3. 在%CATALINA_HOME/conf/logging.properties中,替换默认LogManager:
    logManager=org.apache.logging.log4j.jul.LogManager
    

针对问题3:部分Spring Boot组件日志丢失

日志丢失是因为Spring Boot3的Log4j2上下文与Tomcat的JUL桥接未正确同步,导致部分组件的日志事件未被Log4j2捕获。

解决步骤:

  1. 确保Spring Boot项目中排除默认的JUL依赖,添加Log4j2桥接依赖(在pom.xml中):
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-jul</artifactId>
        <version>2.20.0</version>
        <scope>runtime</scope>
    </dependency>
    <!-- 排除Spring Boot默认的日志依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  2. 在Tomcat启动脚本中添加JVM参数,强制Log4j2接管JUL日志:
    set JAVA_OPTS=%JAVA_OPTS% -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
    
  3. 确保项目中的log4j2.xml/log4j2.properties配置了足够的日志级别,比如对Spring Boot核心包开启DEBUG/INFO级别:
    <Logger name="org.springframework" level="INFO" additivity="false">
        <AppenderRef ref="Console"/>
        <AppenderRef ref="File"/>
    </Logger>
    

内容的提问来源于stack exchange,提问作者user2028936

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:05:22