Search code examples
javagradleintellij-idealog4jslf4j

Why log4j can't find the configuration file


why Intellij Idea gives the error log4j:WARN No appenders could be found for logger (org.gerosd.Manager). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig 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'
}

I tried adding 'org.apache.logging.log4j:log4j-slf4j2-impl:2.20.0', but in this case the configuration was also not read and the error was not written to the console.


Solution

  • It's a dependency problem. You have multiple logging backends on your classpath:

    • log4j-core, which you added explicitly,
    • reload4j, which is a transitive dependency of the SLF4J provider for Reload4j (slf4j-reload4j, which you added explicitly).

    Your dependencies also lack the SLF4J 2.x to Log4j API bridge log4j-slf4j2-impl, so messages logged using SLF4J will end up in Reload4j and those logged using the Log4j API will end up in Log4j Core.

    The solution to this problem depends on the logging API you are using:

    • if you use the Log4j API you need these explicit dependencies:
      dependencies {
       implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
       runtimeOnly 'org.apache.logging.log4j:log4j-core:2.20.0'
       // required by the libraries that use SLF4J
       runtimeOnly 'org.apache.logging.log4j:log4j-slf4j2-impl:2.20.0'
      }
      
    • if you use SLF4J you need these explicit dependencies:
      dependencies {
       implementation 'org.slf4j:slf4j-api:2.0.9'
       runtimeOnly 'org.apache.logging.log4j:log4j-slf4j2-impl:2.20.0'
       runtimeOnly 'org.apache.logging.log4j:log4j-core:2.20.0'
      }