NoSuchMethodError: org.slf4j.impl.StaticLoggerBind

2020-02-05 01:56发布

问题:

The issue was caused by one of the dependencies in my pom.xml [cxf-bundle-jaxrs] which internally uses lower version of slf4j. I managed to resolve this issue by upgrading this dependency to the latest release. Thanks everyone.

I'm trying to add Apache Shiro to my CXF Spring web application. When I start up my tomcat 7 I get the following error

Caused by: java.lang.NoSuchMethodError: org.slf4j.impl.StaticLoggerBinder.getSingleton()Lorg/slf4j/impl/StaticLoggerBinder;
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:121)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:111)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:268)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:241)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:254)
at org.apache.shiro.spring.LifecycleBeanPostProcessor.<clinit>(LifecycleBeanPostProcessor.java:51)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:100)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:61)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:877)
... 25 more

and my pom.xml for shiro and slf4j is

<dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.2.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-web</artifactId>
        <version>1.2.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.2.2</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.1</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
        <scope>runtime</scope>
    </dependency>

I have tried every possible solution by googling, but no luck.

回答1:

Caused by: java.lang.NoSuchMethodError: org.slf4j.impl.StaticLoggerBinder.getSingleton()Lorg/slf4j/impl/StaticLoggerBinder;

This means that you have the class StaticLoggerBinder in your classpath. But the class of your classpath does not have the method getSingleton()

This usually happens when you have dependencies that both use the same transitive dependency. This means that 2 of your dependencies (or your app, and a transitive dependency) are both using SLF4J internally with different versions. But your app can only use a single version of the class at the same time so it has to choose (don't know the rules here... random?)

To solve the problem, you usually need to do a mvn dependency:tree to see which are using different versions of SLF4J.

The solution is often to use a maven dependency exclusion on the lowest version. Libraries like SLF4J tend to be retrocompatible which means newer versions keep adding more features. Sometimes, a method is removed and then you have to keep the old library version, and pray. If this doesn't work there are still some options, like JarJar

But for logging libraries it's sometimes a bit different, so my explaination is for general purpose, but it's probable you do not use the right logging library dependencies because they have very special packagings which are not always easy to understand :)


Check what I found for you:

  • https://github.com/qos-ch/slf4j/blob/SLF4J_1.5.5/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
  • https://github.com/qos-ch/slf4j/blob/SLF4J_1.5.6/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java

The getSingleton() method appeared at version 1.5.6, so it is very probable that you have a library that uses an SLF4J version older that 1.5.6 :) You just need to exclude it with a maven exclusion (and pray).


Edit: you should try:

<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-bundle-jaxrs</artifactId>
  <version>2.2</version>
  <exclusions>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-jdk14</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </exclusion>
  </exclusions> 
</dependency>

Better, if you have a multimodule maven project with a parent pom you can use this with maven dependencyManagement xml node.



回答2:

You need to include this dependency:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.5</version>
</dependency>


回答3:

Something seems to be not compatible with those sl4j-api and log4j versions. Try this link and find the correct and compatible dependencies and use them.

May be you should try the following combination,

SLF4J API Module 1.7.5 The slf4j API

SLF4J LOG4J-12 Binding 1.7.5 SLF4J LOG4J-12 Binding

Or, if you are planning to use version 1.6.1

 <!-- slf4j-log4j -->       
    <dependency>            
          <groupId>org.slf4j</groupId>          
          <artifactId>slf4j-log4j12</artifactId>     
          <version>1.6.1</version>      
    </dependency>


回答4:

Adding this dependency solved the issue for me

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.5</version>
    </dependency>