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

Log4j与Oracle JDK21兼容吗?Jar-in-Jar打包运行报错求助

问题分析与解决方案

这不是Log4j与Oracle JDK21的兼容性问题,根源在于jar-in-jar-loader的反射启动机制破坏了Log4j的调用类检测逻辑。

验证Log4j与JDK21兼容性的方法

  • 编写极简测试类,直接使用Log4j打印日志:
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class TestLog4jCompat {
        private static final Logger logger = LogManager.getLogger(TestLog4jCompat.class);
        public static void main(String[] args) {
            logger.info("Log4j 与 JDK21 兼容测试正常");
        }
    }
    
  • 用JDK21编译该类,将log4j-api-2.22.1.jar和log4j-core-2.22.1.jar加入类路径后运行:
    javac -cp "log4j-api-2.22.1.jar:log4j-core-2.22.1.jar" TestLog4jCompat.java
    java -cp ".:log4j-api-2.22.1.jar:log4j-core-2.22.1.jar" TestLog4jCompat
    
    如果能正常输出日志,说明Log4j与JDK21完全兼容。

问题根源

Log4j的LogManager.callerClass()方法依赖JVM调用栈信息自动识别调用类,但jar-in-jar-loader通过反射启动主类(JarRsrcLoader反射调用a.b.MyApp.main),这种方式会打乱调用栈上下文,导致Log4j无法正确获取调用类,从而抛出异常。而Eclipse中直接运行使用标准类加载器,不会出现此问题。

解决方法

1. 显式指定Logger所属类

将所有无参的LogManager.getLogger()调用改为显式传入当前类对象,避免Log4j自动检测调用类:

// 原代码(有问题)
private static final Logger logger = LogManager.getLogger();
// 修改后
private static final Logger logger = LogManager.getLogger(MyApp.class);

在a.b.log.Log的getLogger方法中,也需要调整为接收类对象参数,让调用方传入具体类。

2. 替换jar-in-jar打包方式

改用标准的依赖合并打包方式,避免反射启动:

  • 若使用Ant,可通过zipgroupfileset将所有依赖合并到单个Jar中,同时修改MANIFEST.MF将Main-Class直接设为a.b.MyApp:
    <jar destfile="myApp.jar" manifest="src/MANIFEST.MF">
        <fileset dir="bin" includes="**/*.class"/>
        <zipgroupfileset dir="lib" includes="**/*.jar"/>
    </jar>
    
    MANIFEST.MF示例:
    Manifest-Version: 1.0
    Main-Class: a.b.MyApp
    Class-Path: .
    

3. 禁用Log4j的调用类检测

在Log4j配置文件(如log4j2.properties)中添加以下配置,关闭自动调用类检测:

log4j2.caller.class.enabled=false

注意:此配置会导致日志中无法显示调用类名,需根据需求取舍。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 18:22:46