ClassCastException: org.slf4j.impl.Log4jLoggerAdap

2020-02-12 02:22发布

问题:

I was following this answer in order to add a appender on runtime. Even though that works for the original poster, I get this exception in line Logger logger = (Logger) LoggerFactory.getLogger("abc.xyz");:

java.lang.ClassCastException: org.slf4j.impl.Log4jLoggerAdapter cannot be cast to ch.qos.logback.classic.Logger
    de.mypackage.controller.MyController.meinOeOrte(MyController.java:335)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:606)
    org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

Simple question... why does it work for him and not for me? :-P

回答1:

This looks like a symptom of having multiple versions of the same dependency (slf4j) in your classpath.

Look in your logs for this message:

SLF4J: Class path contains multiple SLF4J bindings.

It will default to using the first slf4j reference it finds in the classpath. In the past, I've fixed this by moving my Logback dependencies (logback-classic and logback-core) to the top of the dependencies section of my Maven pom.xml file, which places them earlier in the classpath. That's a fragile solution, and it may not work depending on your application architecture. (e.g. if your startup project contains the conflicting dependency in its pom.xml, and you reference Logback through another project and its pom.xml)



回答2:

Due to an already existing dependency of SLF4J in your project or in some other inherited project, there might be conflicts during runtime. Adding an exclusion to my POM file worked for me:

        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>


回答3:

In this case make sure that the library you are using for Logger and LoggerFactory should be the same For example if LoggerFactory is from slf4j then Logger should not be of log4j or java.util. Make sure it is also from slf4j. Let me know if you still face the issue.



回答4:

I resolved it by using logback class libraries and avoid using slf4j. slf4j is only an abstraction and its not mandatory to use. below is the code snippet.

import below classes

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;


LoggerContext context = new LoggerContext();
Logger logger = context.getLogger("testLogger");

Here you go. you have a logger and LoggerContext.