为何Log4j无法找到配置文件?IntelliJ IDEA报无Appender警告
问题现象
运行代码时控制台抛出以下警告:
log4j:WARN No appenders could be found for logger (org.gerosd.Manager).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See ... for more info.
相关代码与配置
Manager.java
package org.gerosd; import org.apache.log4j.PropertyConfigurator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Manager { private static final Logger logger = LoggerFactory.getLogger(Manager.class); public static void main(String[] args) { PropertyConfigurator.configure("D:/work/projects/Log4j/src/main/resources/log4j2.xml"); logger.info("Hello World"); } }
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="LogToConsole" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> <RollingFile name="LogToRollingFile" fileName="logs/app.log" filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="10 MB"/> </Policies> </RollingFile> </Appenders> <Loggers> <!-- avoid duplicated logs with additivity=false --> <Logger name="org.gerosd.Manager" level="warn" additivity="false"> <AppenderRef ref="LogToRollingFile"/> </Logger> <Root level="warn"> <AppenderRef ref="LogToConsole"/> </Root> </Loggers> </Configuration>
build.gradle
plugins { id 'java' } group = 'org.gerosd' version = '1.0-SNAPSHOT' repositories { mavenCentral() } dependencies { implementation 'org.apache.logging.log4j:log4j-core:2.20.0' implementation 'org.apache.logging.log4j:log4j-api:2.20.0' implementation 'org.slf4j:slf4j-api:2.0.9' implementation 'org.slf4j:slf4j-reload4j:2.0.9' }
已尝试操作
添加了org.apache.logging.log4j:log4j-slf4j2-impl:2.20.0依赖,但配置文件仍未被读取,控制台不再输出错误信息。
解决方案
问题根源在于依赖冲突+错误的初始化方式,按以下步骤修复:
1. 调整依赖,移除冲突的桥接包
项目同时引入了slf4j-reload4j(适配Log4j 1.x)和Log4j 2核心包,导致SLF4J绑定到旧的Log4j 1.x实现,无法识别Log4j 2格式的配置。
修改build.gradle的依赖部分,移除slf4j-reload4j,保留log4j-slf4j2-impl作为SLF4J到Log4j 2的桥接:
dependencies { implementation 'org.apache.logging.log4j:log4j-core:2.20.0' implementation 'org.apache.logging.log4j:log4j-api:2.20.0' implementation 'org.slf4j:slf4j-api:2.0.9' // 移除slf4j-reload4j,改用Log4j2的SLF4J桥接 implementation 'org.apache.logging.log4j:log4j-slf4j2-impl:2.20.0' }
2. 替换错误的初始化代码
PropertyConfigurator是Log4j 1.x的初始化类,Log4j 2完全不兼容该API。且配置文件放在src/main/resources下时,Log4j 2会自动扫描加载该目录下的log4j2.xml,无需手动指定路径。
修改Manager.java,删除手动初始化代码:
package org.gerosd; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Manager { private static final Logger logger = LoggerFactory.getLogger(Manager.class); public static void main(String[] args) { // 移除PropertyConfigurator相关代码,Log4j2会自动加载配置 logger.info("Hello World"); } }
3. 调整日志级别(可选)
配置中org.gerosd.Manager的日志级别为warn,而代码调用的是logger.info(),这条日志不会输出。若需看到info级别的日志,修改log4j2.xml中对应Logger的级别:
<Logger name="org.gerosd.Manager" level="info" additivity="false"> <AppenderRef ref="LogToRollingFile"/> </Logger>
4. 验证配置
重新构建项目并运行,此时Log4j 2会自动读取src/main/resources/log4j2.xml,警告信息消失,日志将按照配置输出到控制台和滚动文件中。
内容的提问来源于stack exchange,提问作者gerosd

