日志Jar包冲突问题

背景

  1. 使用淘宝diamond配置工具出现无法配置情况。
  2. 在分析代码、依赖和确认diamond工作无误仍不得解后,最终由好友指点才定位了问题。

分析

异常栈如下

 

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/Workspace/Code/Maven.rep/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/Workspace/Code/Maven.rep/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
Exception in thread "main" java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/Object;Ljava/lang/Throwable;)V
    at org.apache.commons.logging.impl.SLF4JLocationAwareLog.warn(SLF4JLocationAwareLog.java:185)
    at com.starit.diamond.client.impl.DefaultDiamondSubscriber.getAppName(DefaultDiamondSubscriber.java:1539)
    at com.starit.diamond.client.impl.DefaultDiamondSubscriber.<init>(DefaultDiamondSubscriber.java:177)
    at com.starit.diamond.client.impl.DefaultDiamondSubscriber.<init>(DefaultDiamondSubscriber.java:172)
    at com.starit.diamond.client.impl.DefaultDiamondSubscriber$Builder.build(DefaultDiamondSubscriber.java:168)
    at com.starit.diamond.client.impl.DiamondClientFactory.getSingletonDiamondSubscriber(DiamondClientFactory.java:41)
    at com.starit.diamond.manager.impl.DefaultDiamondManager.<init>(DefaultDiamondManager.java:140)
    at com.starit.diamond.manager.impl.DefaultDiamondManager.<init>(DefaultDiamondManager.java:122)
    at com.ustcinfo.inm.data.bolt.tedis.DiamondConfigManager.init(DiamondConfigManager.java:73)
    at com.ustcinfo.inm.data.bolt.tedis.DiamondConfigManager.getInstance(DiamondConfigManager.java:60)
    at com.ustcinfo.inm.data.bolt.Test4Diamond.main(Test4Diamond.java:20)

 

 

繁杂的异常信息,可能让长期处于Deadline边缘的程序猿媛们异常繁杂。但不翻山越岭你怎么能看到彼岸的风景。

 

我们耐下性子,定位异常发生的位置:

 

Exception in thread "main" java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/Object;Ljava/lang/Throwable;)V

 

 

跟踪进log()这个方法

 

  public void warn(Object message) {
    logger.log(null, FQCN, LocationAwareLogger.WARN_INT, String
        .valueOf(message), null, null);
  }

 

 

这时好友怀疑是Jar包冲突。

经典场景为工程中依赖的第三方包都需要使用slf4j这个日志包,一旦这些第三方包中有个使用了较低的slf4j版本中的API,倘若slf4j没有向下兼容而直接删除了这个API,而整个工程又只能使用一个版本的slf4j,那么就会导致由于无法找到这个较低版本的API而编译无法通过。

这时我们在跟进log()这个方法定义的位置

 



 

通过箭头所指的Link with Editor定位类路径,注意上图是依据升级版本之后的图,再未升级之前版本为1.5.8,并且发现其中定义的log()方法如下:

 

public abstract void log(Marker paramMarker, String paramString1, int paramInt, String paramString2, Throwable paramThrowable);

 

仔细对比才发现,1.5.8即我们正在使用的版本中log方法只有5个参数,而diamond中依赖的日志log是6个参数了。

于是我们很自然的升级了slf4j的版本。
这个版本log有6个参数,而问题也得到了解决。

public void log(Marker marker, String fqcn, int level, String message, Object[] argArray, Throwable t);

 

总结

很多时候我们都急于寻求答案,却忘记了最重要的提醒。

请仔细聆听出错日志、异常栈的声音。

 

转载请标明作者和原文链接

ifuteng#gmail.com 2014/7/18

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值