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

升级log4j-layout-template-json后出现IllegalAccessError问题求助

问题

在OpenJDK 17环境下运行Spring Boot应用,使用log4j-layout-template-json包输出JSON格式日志到标准输出。此前使用2.17.2版本一切正常,升级到2.18.0后,应用每次尝试记录日志都会抛出如下错误:

2022-12-13 10:28:59,028 main ERROR An exception occurred processing Appender Console org.apache.logging.log4j.core.appender.AppenderLoggingException: java.lang.IllegalAccessError: class org.apache.logging.log4j.layout.template.json.JsonTemplateLayout$StringBuilderEncoder tried to access method 'void org.apache.logging.log4j.core.layout.TextEncoderHelper.encodeText(java.nio.charset.CharsetEncoder, java.nio.CharBuffer, java.nio.ByteBuffer, java.lang.StringBuilder, org.apache.logging.log4j.core.layout.ByteBufferDestination)' (org.apache.logging.log4j.layout.template.json.JsonTemplateLayout$StringBuilderEncoder and org.apache.logging.log4j.core.layout.TextEncoderHelper are in unnamed module of loader org.springframework.boot.loader.LaunchedURLClassLoader @76fb509a)
    at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:165)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:134)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:125)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:89)
    at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:675)
    at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:633)
    at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:616)
    at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:552)
    at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:82)
    at org.apache.logging.log4j.core.Logger.log(Logger.java:161)
    at org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2205)
    at org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2159)
    at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2142)
    at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:1994)
    at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1852)
    at org.apache.commons.logging.LogAdapter$Log4jLog.log(LogAdapter.java:270)
    at org.apache.commons.logging.LogAdapter$Log4jLog.info(LogAdapter.java:230)
    at org.springframework.boot.StartupInfoLogger.logStarting(StartupInfoLogger.java:55)
    at org.springframework.boot.SpringApplication.logStartupInfo(SpringApplication.java:618)
    at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:377)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
    at org.engine.App.main(App.java:40)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65)
Caused by: java.lang.IllegalAccessError: class org.apache.logging.log4j.layout.template.json.JsonTemplateLayout$StringBuilderEncoder tried to access method 'void org.apache.logging.log4j.core.layout.TextEncoderHelper.encodeText(java.nio.charset.CharsetEncoder, java.nio.CharBuffer, java.nio.ByteBuffer, java.lang.StringBuilder, org.apache.logging.log4j.core.layout.ByteBufferDestination)' (org.apache.logging.log4j.layout.template.json.JsonTemplateLayout$StringBuilderEncoder and org.apache.logging.log4j.core.layout.TextEncoderHelper are in unnamed module of loader org.springframework.boot.loader.LaunchedURLClassLoader @76fb509a)
    at org.apache.logging.log4j.layout.template.json.JsonTemplateLayout$StringBuilderEncoder.encode(JsonTemplateLayout.java:241)
    at org.apache.logging.log4j.layout.template.json.JsonTemplateLayout$StringBuilderEncoder.encode(JsonTemplateLayout.java:216)
    at org.apache.logging.log4j.layout.template.json.JsonTemplateLayout.encode(JsonTemplateLayout.java:304)
    at org.apache.logging.log4j.layout.template.json.JsonTemplateLayout.encode(JsonTemplateLayout.java:58)
    at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:215)
    at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:208)
    at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:199)
    at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:161)
    ... 31 more

升级到2.19.0版本后问题依然存在,且仅在执行打包后的应用Jar时触发,使用Maven运行Surefire/Failsafe测试时无异常。

环境信息

Java版本

$ java --version
openjdk 17.0.5 2022-10-18
OpenJDK Runtime Environment (build 17.0.5+8-Ubuntu-2ubuntu120.04)
OpenJDK 64-Bit Server VM (build 17.0.5+8-Ubuntu-2ubuntu120.04, mixed mode, sharing)

Pom.xml片段

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.3</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-layout-template-json</artifactId>
        <version>2.18.0</version>
    </dependency>
</dependencies>

Log4j配置文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>

    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <JsonTemplateLayout eventTemplateUri="classpath:JSONLogLayout.json"></JsonTemplateLayout>
        </Console>
    </Appenders>
    <Loggers>

        <logger name="org.jooq" level="warn" additivity="false">
            <appender-ref ref="Console" />
        </logger>

        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>

    </Loggers>
</Configuration>
解决方案

问题根源

Spring Boot 2.7.3的parent依赖默认管理的Log4j2版本是2.17.2,但手动将log4j-layout-template-json升级到了2.18.0/2.19.0,导致Log4j2组件版本不一致。2.18.0版本的JsonTemplateLayout$StringBuilderEncoder尝试调用TextEncoderHelper中一个访问权限被修改的方法,而核心的log4j-core还是2.17.2版本,因此触发IllegalAccessError。

修复步骤

方法1:统一Log4j2所有组件版本

在pom.xml的<properties>中指定统一的Log4j2版本,让所有相关依赖自动对齐该版本:

<properties>
    <log4j2.version>2.19.0</log4j2.version>
</properties>

同时移除log4j-layout-template-json依赖中的手动版本指定:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-layout-template-json</artifactId>
</dependency>

方法2:降级回兼容版本

如果不需要升级Log4j2,直接将log4j-layout-template-json版本改回2.17.2,与Spring Boot parent管理的版本保持一致:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-layout-template-json</artifactId>
    <version>2.17.2</version>
</dependency>

方法3:升级Spring Boot版本

将Spring Boot parent版本升级到支持更高Log4j2版本的分支(如2.7.x后续版本或3.x),确保其默认管理的Log4j2版本与你使用的log4j-layout-template-json版本匹配。

测试环境无异常原因

测试时使用的类加载器环境与打包后的Spring Boot LaunchedURLClassLoader不同,测试阶段依赖可能被统一加载,或类加载顺序避免了版本冲突,因此未触发错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:30:25