我有一个spring引导项目,它使用PropertiesLauncher在启动时加载一堆hadoop和hive,以提供到hadoop和hive的连接。我在我的项目中使用带有logback的slf4j,当我加载时,它们会带来导致冲突的log4j类。只要我在build.gradle中使用build.gradle,这就不是问题。
我已经在我的PropertiesLauncher文件中配置了build.gradle
springBoot { layout = 'ZIP' }
bootRepackage {
mainClass = 'com....Application'
enabled = true
} 并使用以下命令启动应用程序
java -Dloader.path=file:///etc/hadoop/conf,file:///etc/hive/conf,jars,
byod-ui-1.0.0.SNAPSHOT.jar -jar byod-ui-1.0.0.SNAPSHOT.jar当项目启动时,输出如下所示
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/byod/byod-ui-1.0.0.SNAPSHOT.jar!/lib/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/byod/jars/hive-jdbc-0.14.0.2.2.8.0-3150-standalone.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/byod/jars/hive-jdbc.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]注意,首先检测到我的应用程序jar,然后检测hive,我假设是因为首先检测到我的jar,最后一行表示选择的绑定是ch.qos.logback.classic.util.ContextSelectorStaticBinder,它是logback,所以一切都很好。
如果我只将spring引导版本(以及代码、配置或jars/类路径设置中的其他任何内容)更改为springBootVersion = '1.3.2.RELEASE',则输出如下所示
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/byod/jars/hive-jdbc.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/byod/jars/hive-jdbc-0.14.0.2.2.8.0-3150-standalone.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/byod/byod-ui-1.0.0.SNAPSHOT.jar!/lib/logback-classic-1.1.3.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 [org.slf4j.impl.Log4jLoggerFactory]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext
but Logback is on the classpath. Either remove Logback or the competing implementation
(class org.slf4j.impl.Log4jLoggerFactory loaded from jar:file:/home/aq728y/byod/jars/hive-jdbc.jar!/).
If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml Object
of class [org.slf4j.impl.Log4jLoggerFactory] must be an instance of class ch.qos.logback.classic.LoggerContext现在检测到的绑定的顺序是不同的。这一次,从hive-jdbc.jar而不是我的应用程序jar中检测到第一个绑定,这导致log4j最终成为“实际绑定”。这将导致错误,应用程序启动失败。
我想提供这些细节,并发布这个问题,看看最近版本的spring中是否有一些变化可以解释这种行为,并可能有助于解决问题。如果可能的话,我想继续使用logback,而不必切换到log4j。
发布于 2016-03-11 17:55:51
在SpringBoot1.3.x中,类路径顺序的处理方式发生了变化。在1.2.x中,顺序被颠倒,因此指定
-Dloader.path=file:///etc/hadoop/conf,file:///etc/hive/conf,jars, byod-ui-1.0.0.SNAPSHOT.jar
产生了以下类路径顺序:
在1.3.x中,类路径不再被恢复,因此相同的命令行选项将导致折叠类路径顺序:
这使得slf4j首先选择了蜂箱中的绑定。因此,解决方案是简单地恢复命令行上的顺序:
-Dloader.path=byod-ui-1.0.0.SNAPSHOT.jar,jars,file:///etc/hive/conf,file:///etc/hadoop/conf
有关更多信息,请参见提交:https://github.com/spring-projects/spring-boot/commit/bfa816f2a30dbc188ca563da8f28c22417d907e5
https://stackoverflow.com/questions/35859607
复制相似问题