45

My code is very simple using apache-log4j-2.0.2:

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

public class Log4jtest {
  static Logger log =Logger.getLogger(Log4jtest.class);
  public static void main(String[] args) {
    BasicConfigurator.configure();
        log.debug("This is debug message");
  }

}

But I'm getting exception like:

Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.ClassCastException: org.apache.logging.slf4j.SLF4JLoggerContext cannot be          cast to org.apache.logging.log4j.core.LoggerContext``
at org.apache.log4j.Logger.getLogger(Logger.java:41)
at Log4jtest.<clinit>(Log4jtest.java:11)

Why is the exception coming from a simple program?

Robert
  • 5,484
  • 1
  • 22
  • 35
user3334466
  • 451
  • 1
  • 4
  • 3
  • 1
    please check your log4j cconfiguration file. – Vineet Kasat Sep 17 '14 at 13:24
  • I had a similar issue. I think I was telling SLF4J to log with a certain binding and then telling log4j to send logging message to SLF4J, which wasn't properly configured, due to the .jars that were included in the classpath. In my case I had a jar like this, that when remove, resolved the issue (by letting log4j log using it's own framework, instead of trying to use the SLFJ framework) log4j-to-slf4j-2.0.2.jar – atom88 Apr 03 '19 at 18:34

2 Answers2

82

Remove below jar's from class path and it should fix the issue -

log4j-to-slf4j-2.0.2.jar
log4j-to-slf4j-2.0.2-sources.jar
log4j-slf4j-impl-2.0.2.jar
log4j-slf4j-impl-2.0.2-sources.jar

I was able to replicate and fix the issue after downloading apache-log4j-2.0.2 from http://www.apache.org/dyn/closer.cgi/logging/log4j/2.0.2/apache-log4j-2.0.2-bin.zip.

TheCodingFrog
  • 3,406
  • 3
  • 21
  • 27
12

I was using Maven. I found that declaring my log4j/slf4j dependencies at the top of the <dependencies> list (before Spring Boot, which used logback) fixed the issue.


To @TheCodingFrog's credit, adding exclusions to my Spring Boot dependencies also solved the problem. Like so:

<dependencies>
    <dependency>
        <groupId>...</groupId>
        <artifactId>...</artifactId>
        <exclusions>
            <exclusion>
                <groupId>log4j</groupId>
                <artifactId>*</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>*</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

NOTE: If you care about which logging framework is actually used, one perhaps important difference is that with @TheCodingFrog's method, slf4j retained logback as the binding:

SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

whereas, with the method I used, slf4j/log4j was used:

SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

In case anyone's interested, the log4j/slf4j dependencies I used are:

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.7</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.7</version>
</dependency>
Hau
  • 443
  • 6
  • 13