140
votes

It appears Springboot autoconfigures itself to use Logback with Tomcat. I would like to disable this and use the one I provide in my classpath.

The error message below.

LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.SimpleLoggerFactory) Object of class [org.slf4j.impl.SimpleLoggerFactory] must be an instance of class ch.qos.logback.classic.LoggerContext

<?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>
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>1.0.1.RELEASE</version>
    </parent>

    <groupId>com.fe</groupId>
    <artifactId>cloudapp</artifactId>
    <version>1.0.0</version>
    <name>Withinet-PaaS</name>
    <description>Develop your web applications in on our infrastructure and we will worry about administration and scalability of your app.</description>

    <properties>
        <java.version>1.7</java.version>
        <guava.version>16.0.1</guava.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-client</artifactId>
        <version>1.8</version>
    </dependency>
        <dependency>
        <groupId>com.withinet.cloudapp</groupId>
    <artifactId>slave</artifactId>
    <version>1.0.0</version>    
        </dependency>
        <dependency>
            <groupId>org.apache.wicket</groupId>
            <artifactId>wicket-core</artifactId>
            <version>6.15.0</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.0.Final</version>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.2.4</version>
        </dependency>

        <!-- Spring Boot -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Hibernate validator -->

        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>


        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator-annotation-processor</artifactId>
            <version>4.1.0.Final</version>
        </dependency>

        <!-- Guava -->

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>

        <!-- Java EE -->

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>

        <!--  Search -->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-queryparser</artifactId>
            <version>4.8.0</version>
        </dependency>

        <!--  Security 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>

        <plugins>

            <!-- Spring Boot Maven -->

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.withinet.cloud.Application</mainClass>
                    <layout>JAR</layout>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>
</project>
22

22 Answers

155
votes

Add exclusion to both the spring-boot-starter and spring-boot-starter-web to resolve the conflict.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
    </exclusion>
  </exclusions>
</dependency>
66
votes

To add a better, more generic solution in Gradle (all instances will be excluded):

configurations {
    all*.exclude module : 'spring-boot-starter-logging'
}

From https://docs.gradle.org/current/userguide/dependency_management.html

42
votes

To add a solution in gradle.

dependencies {
    compile ('org.springframework.boot:spring-boot-starter') {
        exclude module : 'spring-boot-starter-logging'
    }
    compile ('org.springframework.boot:spring-boot-starter-web') {
        exclude module : 'spring-boot-starter-logging'
    }
}
16
votes

I found that excluding the full spring-boot-starter-logging module is not necessary. All that is needed is to exclude the org.slf4j:slf4j-log4j12 module.

Adding this to a Gradle build file will resolve the issue:

configurations {
    runtime.exclude group: "org.slf4j", module: "slf4j-log4j12"
    compile.exclude group: "org.slf4j", module: "slf4j-log4j12"
}

See this other StackOverflow answer for more details.

12
votes

For gradle,

You can see this solution at: http://www.idanfridman.com/how-to-exclude-libraries-from-dependcies-using-gradle/

Just need add exclude in configurations:

configurations {
    providedRuntime
    compile.exclude(group: 'ch.qos.logback')
}
12
votes

Correct way to exclude default logging, and configure log4j for logging.

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter</artifactId>
 <exclusions>
     <exclusion>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-logging</artifactId>
     </exclusion>
 </exclusions>
</dependency>

Refer Spring Logging - How To.

In gradle, I needed to do this with several other dependencies:

configurations {
    all*.exclude module : 'spring-boot-starter-logging'
    all*.exclude module : 'logback-classic'
}
11
votes

I do like this to solve my problem

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>
9
votes

Find spring-boot-starter-test in your pom.xml and modify it as follows:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <exclusions>
            <exclusion>
                <artifactId>commons-logging</artifactId>
                <groupId>commons-logging</groupId>
            </exclusion>
        </exclusions>
        <scope>test</scope>
    </dependency>

It fixed error like:

_Caused by: java.lang.IllegalArgumentException:_ **LoggerFactory** is not a **Logback LoggerContext** but *Logback* is on the classpath.

Either remove **Logback** or the competing implementation

(_class org.apache.logging.slf4j.Log4jLoggerFactory_
loaded from file: 

**${M2_HOME}/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.6.2/log4j-slf4j-impl-2.6.2.jar**).

If you are using WebLogic you will need to add **'org.slf4j'** to prefer-application-packages in WEB-INF/weblogic.xml: **org.apache.logging.slf4j.Log4jLoggerFactory**
8
votes

It might help if you say what your preferred logger is exactly, and what you did to try and install it. Anyway, Spring Boot tries to work with whatever is in the classpath, so if you don't want logback, take it off the classpath. There are instructions for log4j in the docs, but the same thing would apply to other supported logging systems (anything slf4j, log4j or java util).

7
votes

Following works for me

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
5
votes

I resolved my problem through this below:

compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.0'){
    exclude module: 'log4j-slf4j-impl'
    exclude module: 'logback-classic'
}
compile('org.springframework.boot:spring-boot-starter-web'){
    exclude module: 'log4j-slf4j-impl'
    exclude module: 'logback-classic'
}
5
votes

This worked for me just fine

configurations {
    all*.exclude module : 'spring-boot-starter-logging'
}

But it wouldn't work out for maven users. All my dependencies was in libs.gradle and I didn't want them in other files. So this problem was solved by adding exclude module : 'spring-boot-starter-logging in spring-boot-starter-data-jpa, spring-boot-starter-test and in practically everything with boot word.

UPDATE

New project of mine needed an update, turns out spring-boot-starter-test 1.5 and older didn't have spring-boot-starter-logging. 2.0 has it

5
votes

In my case, it was only required to exclude the spring-boot-starter-logging artifact from the spring-boot-starter-security one.

This is in a newly generated spring boot 2.2.6.RELEASE project including the following dependencies:

  • spring-boot-starter-security
  • spring-boot-starter-validation
  • spring-boot-starter-web
  • spring-boot-starter-test

I found out by running mvn dependency:tree and looking for ch.qos.logback.

The spring boot related <dependencies> in my pom.xml looks like this:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>           
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <scope>test</scope>
    </dependency>



</dependencies>
5
votes

Same problem for me.

enter image description here

If you are using log4j2

In the Spring boot 2.4.0

I resolve below,

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId> <-- exclude this artifactId
        </exclusion>
    </exclusions>
</dependency>

After, Maven Build > Clean > Run

enter image description here

Work for me.

4
votes

Add this in your build.gradle

configurations.all {
    exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
    exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    exclude group: 'org.springframework.boot', module: 'logback-classic'
}
2
votes

If this error occurred in SpringBoot when you are trying to use log4j2 then do these steps:

  • Remove the jar from while packeging by adding this "excludeGroupIds log4j-slf4j-impl /excludeGroupIds"
  • Find out the which library is depends on "logback-classic" by using command "mvn dependecy:tree"
  • Wherever you find it exclude it from the dependency.

This error occurred because logback override the log4j2 changes. SO if you want to use log4j2 then you have to remove logback library and dependencies.

Hope this will help someone.

2
votes

Using Gradle & Lombok, here is the simplest configuration for Log4j2 that worked for me using the latest Spring Boot (2.4.1 at this time) :

build.gradle (partial)

configurations {
    compileOnly { extendsFrom annotationProcessor }
    compile.exclude module: 'spring-boot-starter-logging'
}


dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-security' 
    implementation 'org.springframework.boot:spring-boot-starter-web-services'
    implementation 'org.springframework.boot:spring-boot-starter-log4j2'

    compileOnly 'org.projectlombok:lombok'

    // (*** other dependencies ***)

    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'
}

I noticed you will get errors if you include spring-bbot-starter-log4j2 as a compileOnly dependency instead of as an implementation.

Just annotate your classes with @Log4j2 (or @Slf4j) and lombok will make available a log variable you can use for logging.

As usual, provide a log4j2.xml configuration file in your /src/main/resources folder.

1
votes

To add an exclusion for logback from Netbeans IDE

  1. Access the >Projects explorer section for your project
  2. Proceed to >Dependencies as displayed below
  3. Trace 'spring-boot-starter-logging-X.X.X.jar'
  4. Right click on the jar and select Exclude Dependency as shown below. This excludes the logback jar on the pom.xml like this;

      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    

enter image description here

1
votes

In my case below exclusion works!!

    <dependency>
        <groupId>com.xyz.util</groupId>
        <artifactId>xyz-web-util</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
1
votes

Adding exclusions was not enough for me. I had to provide a fake jar:

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <scope>system</scope>
        <systemPath>${project.basedir}/empty.jar</systemPath>
    </dependency>
1
votes

The reason is, spring boot comes with logback as its default log configuration whereas camel uses log4j. Thats the reason of conflict. You have two options, either remove logback from spring boot as mentioned in above answers or remove log4j from camel.

<dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-spring-boot-starter</artifactId>
            <version>${camel.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
0
votes

Just add logback.xml configuration in your classpath and add all your configuration with root appender added. Once the Spring boot completes the bean loading, it will start logging based on your configuration.