spring-bootslf4j

Spring Boot log4j ClassPath contains multiple `SLF4J` bindings


I have a Spring Boot project and I want to add SLF4J to my project.

I created a file named log4j.properties and here is it's body:

log4j.rootLogger=ALL, STDOUT
log4j.appender.STDOUT= org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout = org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm} %t [%-5p]-%c:%m%n

and here is my build.gradle:

plugins {
    id 'org.springframework.boot' version '2.6.7'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'io.project'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = "17"

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springdoc:springdoc-openapi-ui:1.6.8'
    implementation 'org.hibernate.validator:hibernate-validator:7.0.4.Final'
    implementation 'org.mapstruct:mapstruct:1.4.2.Final'

    implementation 'org.slf4j:slf4j-api:1.7.36'
    implementation 'org.slf4j:slf4j-log4j12:1.7.36'

    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
    runtimeOnly 'com.h2database:h2'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.2'

}

tasks.named('test') {
    useJUnitPlatform()
}
targetCompatibility = JavaVersion.VERSION_17

when I run the project I get this error

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/mbunderline76/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-reload4j/1.7.36/db708f7d959dee1857ac524636e85ecf2e1781c1/slf4j-reload4j-1.7.36.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/mbunderline76/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.2.11/4741689214e9d1e8408b206506cbe76d1c6a7d60/logback-classic-1.2.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]`

Solution

  • By default, Spring Boot uses spring-boot-starter-logging with a logback as a backend for logging. In order to use log4j you need to exclude spring-boot-starter-logging.

    configurations {
        all {
            exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
        }
    }
    

    In addition, instead of adding slf4j-log4j directly, include

    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-log4j2'