How to configure a Gradle application to use SLF4J with a Log4J 2 implementation?

Viewed 3189

I'm trying to configure a Gradle project (which uses Lombok annotation processors) to use SLF4J with a Log4j 2 implementation. The project - which was started using gradle init and selecting an application - has the following structure:

.
├── app
│   ├── build
│   │   ├── classes
│   │   │   └── java
│   │   │       └── main
│   │   │           └── log4j
│   │   │               └── App.class
│   │   ├── generated
│   │   │   └── sources
│   │   │       ├── annotationProcessor
│   │   │       │   └── java
│   │   │       │       └── main
│   │   │       └── headers
│   │   │           └── java
│   │   │               └── main
│   │   └── tmp
│   │       └── compileJava
│   │           └── source-classes-mapping.txt
│   ├── build.gradle
│   └── src
│       ├── main
│       │   ├── java
│       │   │   └── log4j
│       │   │       └── App.java
│       │   └── resources
│       └── test
│           ├── java
│           │   └── log4j
│           │       └── AppTest.java
│           └── resources
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── log4j2.xml
└── settings.gradle

I've put a log4j2.xml file in the project directory. According to step 9 in the Automatic Configuration section of https://logging.apache.org/log4j/2.x/manual/configuration.html,

If a JSON file cannot be located the XML ConfigurationFactory will try to locate log4j2.xml on the classpath.

My build.gradle has the needed dependencies,

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java application project to get you started.
 * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
 * User Manual available at https://docs.gradle.org/6.8.1/userguide/building_java_projects.html
 */

plugins {
    // Apply the application plugin to add support for building a CLI application in Java.
    id 'application'
}

repositories {
    // Use JCenter for resolving dependencies.
    jcenter()
}

dependencies {
    // Use JUnit test framework.
    testImplementation 'junit:junit:4.13'

    // This dependency is used by the application.
    implementation 'com.google.guava:guava:29.0-jre'

    implementation group: 'org.slf4j', name: 'slf4j-api', version: '2.0.0-alpha1'
    implementation 'org.apache.logging.log4j:log4j-slf4j18-impl:2.14.0'

    compileOnly 'org.projectlombok:lombok:1.18.16'
    annotationProcessor 'org.projectlombok:lombok:1.18.16'

    testCompileOnly 'org.projectlombok:lombok:1.18.16'
    testAnnotationProcessor 'org.projectlombok:lombok:1.18.16'
}

application {
    // Define the main class for the application.
    mainClass = 'log4j.App'
}

and the App class itself is

package log4j;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class App {
    public String getGreeting() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        log.info("Printing a greeting...");
        System.out.println(new App().getGreeting());
    }
}

The problem is that if I run the application using ./gradlew run, it doesn't print the log.info() line,

> ./gradlew run

> Task :app:run
Hello World!

whereas if I change it to log.error(), it does get logged:

> ./gradlew run

> Task :app:run
19:26:50.782 [main] ERROR log4j.App - Printing a greeting...
Hello World!

Since I've set the level to trace in the log4j2.xml configuration file,

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

I would suggest info-level logs to get displayed if the configuration file were 'picked up'. This suggest to me that it is not in the class path. I've tried copying it to the app directory but to no avail. Where should the log4j2.xml configuration file be located to correctly configure Log4J 2?

1 Answers
Related