Log4j 2.x初始化耗时数秒,Maven项目启动阻塞求助
Log4j 初始化耗时6秒阻塞应用启动(M1 macOS环境)
在Maven项目中引入Log4j 2.x(2.17.0到2.20.0版本均测试过),发现首次调用LogManager.getLogger()时耗时约6秒,由于Logger通常定义为静态类变量,导致应用启动时直接被阻塞,严重影响开发效率和体验。
运行环境:2020款M1 MacBook Air(AArch64)- macOS Ventura 13.2.1
项目配置与代码
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>Example</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>19</maven.compiler.source> <maven.compiler.target>19</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.20.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.20.0</version> <scope>compile</scope> </dependency> </dependencies> </project>
Main.java
package com.example; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import javax.swing.JFrame; public class Main { private static final Logger logger = LogManager.getLogger(); public static void main(String[] args) { logger.info("application launched"); var frame = new JFrame(); frame.setSize(233, 377); frame.setVisible(true); } }
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
解决方案
原因分析
这个问题是M1 macOS环境下,Log4j初始化时会触发JDK的InetAddress.getLocalHost()调用,而该调用在部分M1设备上会因为DNS解析延迟导致耗时过长,进而阻塞Logger的初始化流程。
具体解决步骤
修正hosts文件解析
- 终端执行
sudo nano /etc/hosts - 添加以下两行(替换
your-hostname为你通过hostname命令查到的主机名):127.0.0.1 your-hostname.local ::1 your-hostname.local - 按
Ctrl+O保存,Ctrl+X退出,再执行sudo dscacheutil -flushcache刷新DNS缓存。
- 终端执行
强制Log4j使用固定主机名
在log4j2.xml的Configuration节点添加hostname="localhost"属性,跳过系统DNS解析:<Configuration status="WARN" hostname="localhost"> <!-- 原配置内容不变 --> </Configuration>升级Log4j到最新稳定版
后续版本可能针对M1平台做了优化,建议尝试2.22.0及以上版本,直接更新pom.xml中的依赖版本即可。临时懒加载Logger
如果上述方法暂时无法生效,可以把Logger初始化从静态变量改为启动后延迟加载,避免阻塞UI启动:private static Logger logger; public static void main(String[] args) { // 先启动界面 var frame = new JFrame(); frame.setSize(233, 377); frame.setVisible(true); // 再初始化Logger logger = LogManager.getLogger(); logger.info("application launched"); }
内容的提问来源于stack exchange,提问作者mammut
相关产品推荐
相关产品推荐

