springboot resolution of Class path contains multiple SLF4J bindings. Warning
Once, after the springboot project was configured and started, the following warning was suddenly found:
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/E:/mavenJarOnline/ch/qos/logback/logback-classic/1.1.9/logback-classic-1.1.9.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/E:/mavenJarOnline/org/slf4j/slf4j-log4j12/1.7.22/slf4j-log4j12-1.7.22.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
Cause analysis:
The above roughly means that the logback classic package and slf4j-log4j12 package conflict with the org/slf4j/impl/StaticLoggerBinder.class class class.
The reason for this error is that first of all, the developers of logback log and log4j are said to be a wave of people, while the default log of springboot is the newer logback log. But in the past, the popular log was log4j, and many third-party tools included log4j.
In our project development, we will inevitably introduce various toolkits. Therefore, basically, if we do not pay attention to the springboot project, this conflict will certainly occur.
Potential problems:
Of course, the most concern is whether it has hidden dangers. If you run it in the development tool, yes, there is no problem. It will generally start normally.
After my observation in the usage, it seems that the spring boot is configured to run in tomcat, that is, after it is modified to war package, this warning generally has no impact; However, if it is a traditional jar package, although you can run normally in the development tool, it may not run after typing the package.
Problem:
Because we are a distributed project development, the service layer runs as a jar, and the interface call and the front-end page run together as a war, that is, we have both war and jar. When the project is deployed, we need to run after the package is completed.
After typing the package, the war package can run normally, but the jar package cannot run normally. The following error is reported:
Exception in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner .java:48) at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) Caused by: java.lang.ExceptionInInitializerError at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:72) at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:45 ) at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150) at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124) at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357) at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogF actory.java:155) at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogF actory.java:132) at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:273) at org.springframework.boot.SpringApplication.<clinit>(SpringApplication .java:190) at spingboot.study.SpringbootStudyApplication.main(SpringbootStudyApplic ation.java:14) ... 8 more Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar A ND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details. at org.slf4j.impl.Log4jLoggerFactory.<clinit>(Log4jLoggerFactory.java:54 ) ... 19 more
Problem solving:
Of course, I'm not sure. It must be because of war and jar. You may not care about this. We just want to know how to solve this problem.
The solution to the problem is very simple. Since the jar package conflict is discarded, we can exclude one jar package. The key is to exclude which jar package. Note here. If you use logback logs, you must exclude slf4j-log4j12 package, not logback classic package.
That is, find the pom.xml file. If your development tools, such as eclipse and idea, can see the connection of introducing jar packages. For example, idea can see your dependency structure in this way:
After clicking, the following structure will pop up:
From the above figure, you can see that the slf4j-log4j12 package is introduced by default in the zookeeper package. In addition, there is the spring boot starter web package that we must introduce in spring boot, which also has the slf4j-log4j12 introduction.
We just need to exclude this in pom.xml.
As follows:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!--Exclude this slf4j-log4j12--> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency>
The following is the third-party toolkit introduced by our project:
<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.8</version> <!--Exclude this slf4j-log4j12--> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency>