SLF4J error: class loader have different class objects for the type

SLF4J error: class loader have different class objects for the type

试图找出为什么我在 tomcat 日志中收到以下错误:

Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/apache/catalina/loader/WebappClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature

在我的 gradle 文件中,我使用的是 slf4j 版本 1.7.7,在 tomcat 中,我有 jul-to-slf4j-1.7.7.jar 和 slf4j-api-1.7.7.jar,所以我很困惑。

这是堆栈跟踪 - 感谢您的帮助!

Total time: 2.982 secs
Using CATALINA_BASE:   /usr/local/Cellar/tomcat/8.0.18/libexec
Using CATALINA_HOME:   /usr/local/Cellar/tomcat/8.0.18/libexec
Using CATALINA_TMPDIR: /usr/local/Cellar/tomcat/8.0.18/libexec/temp
Using JRE_HOME:        /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home
Using CLASSPATH:       /usr/local/Cellar/tomcat/8.0.18/libexec/bin/jul-to-slf4j-1.7.7.jar:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/slf4j-api-1.7.7.jar:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/logback-classic-1.1.2.jar:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/logback-core-1.1.2.jar:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/logback-config/:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/bootstrap.jar:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/tomcat-juli.jar
19:03:55.979 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - Server version:        Apache Tomcat/8.0.18
19:03:55.981 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - Server built:          Jan 23 2015 11:56:07 UTC
19:03:55.981 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - Server number:         8.0.18.0
19:03:55.982 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - OS Name:               Mac OS X
19:03:55.982 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - OS Version:            10.10
19:03:55.982 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - Architecture:          x86_64
19:03:55.982 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - Java Home:             /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre
19:03:55.982 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - JVM Version:           1.8.0_25-b17
19:03:55.982 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - JVM Vendor:            Oracle Corporation
19:03:55.982 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - CATALINA_BASE:         /usr/local/Cellar/tomcat/8.0.18/libexec
19:03:55.983 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - CATALINA_HOME:         /usr/local/Cellar/tomcat/8.0.18/libexec
19:03:55.983 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - Command line argument: -Djava.util.logging.config.file=/usr/local/Cellar/tomcat/8.0.18/libexec/conf/logging.properties
19:03:55.983 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
19:03:55.983 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - Command line argument: -Djava.endorsed.dirs=/usr/local/Cellar/tomcat/8.0.18/libexec/endorsed
19:03:55.983 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - Command line argument: -Dcatalina.base=/usr/local/Cellar/tomcat/8.0.18/libexec
19:03:55.984 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - Command line argument: -Dcatalina.home=/usr/local/Cellar/tomcat/8.0.18/libexec
19:03:55.984 [main] INFO  org.apache.catalina.startup.VersionLoggerListener - Command line argument: -Djava.io.tmpdir=/usr/local/Cellar/tomcat/8.0.18/libexec/temp
19:03:55.984 [main] INFO  org.apache.catalina.core.AprLifecycleListener - The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /Users/jadekler/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
19:03:56.076 [main] INFO  org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]
19:03:56.092 [main] INFO  org.apache.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
19:03:56.094 [main] INFO  org.apache.coyote.ajp.AjpNioProtocol - Initializing ProtocolHandler ["ajp-nio-8009"]
19:03:56.096 [main] INFO  org.apache.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
19:03:56.096 [main] INFO  org.apache.catalina.startup.Catalina - Initialization processed in 510 ms
19:03:56.115 [main] INFO  org.apache.catalina.core.StandardService - Starting service Catalina
19:03:56.115 [main] INFO  org.apache.catalina.core.StandardEngine - Starting Servlet Engine: Apache Tomcat/8.0.18
19:03:56.132 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deploying web application archive /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/websiteskeleton.war
19:03:56.812 [localhost-startStop-1] ERROR org.apache.catalina.core.StandardContext - Error during ServletContainerInitializer processing
javax.servlet.ServletException: Failed to instantiate WebApplicationInitializer class
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:160) ~[spring-web-4.1.0.RELEASE.jar:4.1.0.RELEASE]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5143) ~[catalina.jar:8.0.18]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:8.0.18]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725) [catalina.jar:8.0.18]
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) [catalina.jar:8.0.18]
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:714) [catalina.jar:8.0.18]
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:917) [catalina.jar:8.0.18]
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1701) [catalina.jar:8.0.18]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_25]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_25]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_25]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_25]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25]
Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/apache/catalina/loader/WebappClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:306) ~[slf4j-api-1.7.7.jar:1.7.7]
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:276) ~[slf4j-api-1.7.7.jar:1.7.7]
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:288) ~[slf4j-api-1.7.7.jar:1.7.7]
    at com.websiteskeleton.core.HelloInitializer.<init>(HelloInitializer.java:13) ~[HelloInitializer.class:na]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_25]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_25]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_25]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408) ~[na:1.8.0_25]
    at java.lang.Class.newInstance(Class.java:438) ~[na:1.8.0_25]
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:157) ~[spring-web-4.1.0.RELEASE.jar:4.1.0.RELEASE]
    ... 12 common frames omitted
19:03:56.821 [localhost-startStop-1] ERROR org.apache.catalina.core.StandardContext - Context [/websiteskeleton] startup failed due to previous errors
19:03:56.825 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deployment of web application archive /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/websiteskeleton.war has finished in 693 ms
19:03:56.826 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deploying web application directory /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/docs
19:03:56.893 [localhost-startStop-1] INFO  org.apache.jasper.servlet.TldScanner - At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
19:03:56.904 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deployment of web application directory /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/docs has finished in 78 ms
19:03:56.904 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deploying web application directory /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/examples
19:03:57.133 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deployment of web application directory /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/examples has finished in 228 ms
19:03:57.133 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deploying web application directory /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/host-manager
19:03:57.192 [localhost-startStop-1] INFO  org.apache.jasper.servlet.TldScanner - At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
19:03:57.195 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deployment of web application directory /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/host-manager has finished in 62 ms
19:03:57.195 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deploying web application directory /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/manager
19:03:57.252 [localhost-startStop-1] INFO  org.apache.jasper.servlet.TldScanner - At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
19:03:57.254 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deployment of web application directory /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/manager has finished in 59 ms
19:03:57.254 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deploying web application directory /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/ROOT
19:03:57.307 [localhost-startStop-1] INFO  org.apache.jasper.servlet.TldScanner - At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
19:03:57.308 [localhost-startStop-1] INFO  org.apache.catalina.startup.HostConfig - Deployment of web application directory /usr/local/Cellar/tomcat/8.0.18/libexec/webapps/ROOT has finished in 54 ms
19:03:57.310 [main] INFO  org.apache.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
19:03:57.314 [main] INFO  org.apache.coyote.ajp.AjpNioProtocol - Starting ProtocolHandler ["ajp-nio-8009"]
19:03:57.315 [main] INFO  org.apache.catalina.startup.Catalina - Server startup in 1218 ms

Tomcat 日志显示您在 class 路径上有另一个 slf4j-1.7.7.jar:

使用 CLASSPATH:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/jul-to-slf4j-1.7.7.jar:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/slf4j-api-1.7 .7.jar:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/logback-classic-1.1.2.jar:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/logback-core-1.1. 2.jar:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/logback-config/:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/bootstrap.jar:/usr/local/Cellar/tomcat/8.0.18/libexec/bin/tomcat-juli .jar

初始化Tomcat时,会初始化jul-to-slf4j和slf4j-api。这些 jar 由加载 Tomcat jar (sun/misc/Launcher$AppClassLoader) 的类加载器加载。

当您的应用程序尝试访问 slf4j-api classes 时,它使用 WebApplication 类加载器 (org/apache/catalina/loader/WebappClassLoader),它默认搜索 classes在系统 class 路径之前的应用程序 class 路径上定义。请注意,这可以更改:https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

在Java中,class签名由class全限定名和加载class的class加载器组成。如果一个 class 从两个不同的 class 加载器(同一层次结构)加载两次,则 JVM 将有两个不同的 classes。试图将一个 class 的对象引用指向另一个的变量将引发 ClassCastException。查看此博客 post(第 5 项)以获取更多信息:https://techblug.wordpress.com/2012/03/17/classloader-tips/

因此,据我所知,您可以通过从 Tomcat class 路径中删除 slf4j-*.jar 来解决此问题,或者如果您有多个使用相同的 Web 应用程序slf4j 版本,您可以从 webapp 中删除 jar,因此它将使用由 Tomcat classloader.

加载的那些