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

Log4j2自定义TextAreaAppender经ProGuard混淆后无法正常工作

ProGuard混淆后Log4j2自定义TextAreaAppender加载异常问题

应用经ProGuard混淆后,自定义的Log4j2 TextAreaAppender出现加载失败。未混淆的输入Jar运行正常,即使跳过所有类(含依赖)的混淆,错误依然存在。当前使用maven-assembly-plugin生成包含依赖的Jar包。

报错信息

2023-09-28 23:42:58,309 JavaFX Application Thread ERROR Error processing element TextAreaAppender ([Appenders: null]): CLASS_NOT_FOUND
2023-09-28 23:42:58,488 JavaFX Application Thread ERROR Unable to locate appender "JavaFXLogger" for logger config "root"

自定义TextAreaAppender代码

package my.package;

import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.io.Serializable;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javafx.scene.control.CodeArea;

@Plugin(
        name = "TextAreaAppender",
        category = "Core",
        elementType = Appender.ELEMENT_TYPE,
        printObject = true)
public final class TextAreaAppender extends AbstractAppender {
    private static final Logger logger = LogManager.getLogger();

    private static CodeArea textArea;
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final Lock readLock = rwLock.readLock();


    public TextAreaAppender(String name, Filter filter,
                            Layout<? extends Serializable> layout,
                            final boolean ignoreExceptions) {
        super(name, filter, layout, ignoreExceptions);
    }

    @PluginFactory
    public static TextAreaAppender createAppender(
            @PluginAttribute("name") String name,
            @PluginElement("Layout") Layout<? extends Serializable> layout,
            @PluginElement("Filter") final Filter filter) {
        if (name == null) {
            logger.error("No name provided for TextAreaAppender");
            return null;
        }
        if (layout == null) {
            layout = PatternLayout.createDefaultLayout();
        }
        return new TextAreaAppender(name, filter, layout, true);
    }

    @Override
    public void append(LogEvent event) {
        readLock.lock();
        // 日志输出逻辑
        readLock.unlock();
    }
}    

log4j2.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="my.package" >

    <!-- Logging Properties -->
    <Properties>
        <Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} | %-5p | [%thread] (%F:%L) - %m%n</Property>
        <Property name="LOG_LEVEL">INFO</Property>
        <Property name="APP_LOG_ROOT">logs</Property>
    </Properties>

    <Appenders>
        <TextAreaAppender name="JavaFXLogger">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </TextAreaAppender>
    </Appenders>

    <Loggers>
        <Logger name="my" additivity="false" level="${LOG_LEVEL}">
            <AppenderRef ref="JavaFXLogger"/>
        </Logger>

        <Root level="${LOG_LEVEL}">
            <AppenderRef ref="JavaFXLogger"/>
        </Root>
    </Loggers>

</Configuration>

问题解决方法

Log4j2依赖@Plugin注解识别自定义Appender,ProGuard即便不混淆类名,也可能移除注解信息、优化未直接引用的类/方法,导致Log4j2扫描不到自定义Appender。需添加以下ProGuard规则:

1. 核心ProGuard配置规则

# 保留自定义Appender类及所有成员
-keep class my.package.TextAreaAppender {
    *;
}

# 保留注解元数据(Log4j2插件识别必需)
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable

# 保留PluginFactory注解标记的工厂方法
-keepclassmembers class my.package.TextAreaAppender {
    @org.apache.logging.log4j.core.config.plugins.PluginFactory *;
}

# 保留Log4j2插件扫描相关类
-keep class org.apache.logging.log4j.core.config.plugins.** { *; }

2. 打包与配置检查

  • 确认maven-assembly-plugin打包后,my.package.TextAreaAppender类存在于Jar中,log4j2.xml配置文件位于Jar的resources目录或根目录。
  • 核对log4j2.xml中packages="my.package"是否准确指向自定义Appender所在包。

3. 验证手段

临时添加ProGuard参数-dontshrink和-dontoptimize,若问题消失,说明是压缩/优化导致的类或注解被移除,需调整keep规则覆盖相关内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 15:11:02