遇到了同样的问题,

我的解决办法是在pom.xml中增加如下配置,去除对于jcl-over-slf4j.jar的依赖。

    <exclusions>
                <exclusion>
                    <artifactId>jcl-over-slf4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>

顺便转载下大神解答:

转载自:http://blog.csdn.net/xian00000/article/details/10013395

今天启动tomcat服务失败,碰到异常情况如下

java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;Ljava/lang/Throwable;)V
    at org.apache.commons.logging.impl.SLF4JLocationAwareLog.info(SLF4JLocationAwareLog.java:159)

Commons-log + log4j 这黄金搭档一直以来都让我们很省心,很好的完成了日志的需求。但是随着技术的变更和对性能的追求,slf4j 和 logback 这对后起之秀的到来好像打破了原本很平静的日志系统,频繁的出现包冲突...

和平的日子不在了,让我们一起来看看究竟发生了什么...

首先看看这些个包,特别是slf4j引入后就引入了一大堆包之后就有点懵了。

为什么commons-logging和jcl-over-slf4j会有冲突呢?看一下它们的类结构

很清晰的可以看到jcl-over-slf4j 重写了 commons-logging...

还有slf4j-api的实现呢,同样看类:

其实就这么简单,往往看了代码之后才发现错误是这么显而易见。。。

顺着研究,继续看一下slf4j的源码及流程

1.测试类

java代码

  1. package com.taobao.wuzhong.log;
  2. import org.apache.commons.logging.Log;
  3. import org.apache.commons.logging.LogFactory;
  4. import org.junit.Test;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. /**
  8. * DESC:
  9. *
  10. * Copyright: Copyright 2011 m.taobao.com
  11. *
  12. * @author wuzhong@taobao.com
  13. * @time 2011-4-6 下午03:42:11
  14. * @version 1.0
  15. **/
  16. public class LogTest {
  17. // Logback tries to find a file called logback.groovy in the classpath.
  18. // If no such file is found, logback tries to find a file called
  19. // logback-test.xml in the classpath.
  20. // If no such file is found, it checks for the file logback.xml in the
  21. // classpath..
  22. // If neither file is found, logback configures itself automatically using
  23. // the BasicConfigurator which will cause logging output to be directed to
  24. // the console.
  25. @Test
  26. public void test() {
  27. //commons-logging的方式获取
  28. Log log = LogFactory.getLog(LogTest.class);
  29. //slf4j直接的方式获取,推荐用这个
  30. Logger log2 = LoggerFactory.getLogger(LogTest.class);
  31. log.debug("eeeeee {} {} {}");
  32. log2.debug("{} {} {}", new String[] { "a", "b", "c" });
  33. }
  34. }

logFactory.getLog 会调用内部静态变量 Slf4jLogFactory.getInstance方法,如下:

public Log getInstance(String name) throws LogConfigurationException {

  1. Log instance = null;
  2. // protect against concurrent access of loggerMap
  3. synchronized (this) {
  4. instance = (Log) loggerMap.get(name);
  5. if (instance == null) {
  6. Logger logger = LoggerFactory.getLogger(name);   //slf4j的方式,代理过去了
  7. if(logger instanceof LocationAwareLogger) {
  8. instance = new SLF4JLocationAwareLog((LocationAwareLogger) logger);  //包装了一层,做适配
  9. } else {
  10. instance = new SLF4JLog(logger);
  11. }
  12. loggerMap.put(name, instance);
  13. }
  14. }
  15. return (instance);

loggerFactory 会调用getILoggerFactory().getlOgger()

  1. LoggerFactory.java
  2. public static ILoggerFactory getILoggerFactory() {
  3. if (INITIALIZATION_STATE == UNINITIALIZED) {
  4. INITIALIZATION_STATE = ONGOING_INITILIZATION;
  5. performInitialization();
  6. }
  7. switch (INITIALIZATION_STATE) {
  8. case SUCCESSFUL_INITILIZATION:
  9. return getSingleton().getLoggerFactory();
  10. case FAILED_INITILIZATION:
  11. throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
  12. case ONGOING_INITILIZATION:
  13. // support re-entrant behavior.
  14. // See also http://bugzilla.slf4j.org/show_bug.cgi?id=106
  15. return TEMP_FACTORY;
  16. }
  17. throw new IllegalStateException("Unreachable code");
  18. }
  19. private final static void performInitialization() {
  20. bind();
  21. versionSanityCheck();
  22. singleImplementationSanityCheck();
  23. }

这里的bind很关键,这里动态的绑定了slf4j-api的实现机制

  1. static {
  2. SINGLETON.init();
  3. }
  4. /**
  5. * Package access for testing purposes.
  6. */
  7. void init() {
  8. try {
  9. try {
  10. new ContextInitializer(defaultLoggerContext).autoConfig();
  11. } catch (JoranException je) {
  12. Util.reportFailure("Failed to auto configure default logger context",
  13. je);
  14. }
  15. StatusPrinter.printInCaseOfErrorsOrWarnings(defaultLoggerContext);
  16. contextSelectorBinder.init(defaultLoggerContext, KEY);
  17. initialized = true;
  18. } catch (Throwable t) {
  19. // we should never get here
  20. Util.reportFailure("Failed to instantiate ["
  21. + LoggerContext.class.getName() + "]", t);
  22. }
  23. }

获取配置信息初始化

  1. autoConfig ….
  2. public URL findURLOfDefaultConfigurationFile(boolean updateStatus) {
  3. ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);
  4. URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus);
  5. if (url != null) {
  6. return url;
  7. }
  8. url = Loader.getResource(TEST_AUTOCONFIG_FILE, myClassLoader);
  9. if (updateStatus) {
  10. statusOnResourceSearch(TEST_AUTOCONFIG_FILE, myClassLoader, url);
  11. }
  12. if (url != null) {
  13. return url;
  14. }
  15. url = Loader.getResource(AUTOCONFIG_FILE, myClassLoader);
  16. if (updateStatus) {
  17. statusOnResourceSearch(AUTOCONFIG_FILE, myClassLoader, url);
  18. }
  19. return url;
  20. }
  21. public void autoConfig() throws JoranException {
  22. StatusListenerConfigHelper.installIfAsked(loggerContext);
  23. URL url = findURLOfDefaultConfigurationFile(true);
  24. if (url != null) {
  25. configureByResource(url);
  26. } else {
  27. BasicConfigurator.configure(loggerContext);
  28. }
  29. }

最后画张流程图总结下,^_^

总结: log框架应该很好的诠释了 facade , adapter , 实现上还是比较简单的,很好的做到了接口和实现的分离,对今后的代码组织有一定的启发

转载自 : http://myclqr.iteye.com/blog/1775541

------------------------------------------------------------------------------------

用slf4j+logback替代commons-logging+log4j
加载以下jar包:
slf4j-api.jar
logback-core.jar
logback-classic.jar
log4j-over-slf4j.jar
jcl104-over-slf4j.jar
同时删除commons-logging.jar和log4j.jar
http://logback.qos.ch/translator/Welcome.do转换log4j.properties为logback.xml

log日志框架和LocationAwareLogger问题的更多相关文章

  1. Spring Boot Log 日志使用教程

    我们编写任何 Spring Boot 程序,可能绕不开的就是 log 日志框架(组件). 在大多数程序员眼中日志是用来定位问题的.这很重要. 本项目源码下载 注意本项目提供的源码已在后期重新编写,有部 ...

  2. scrapy框架之log日志

    scrapy中的debug信息 在scrapy中设置log 1.在settings中设置log级别,在settings.py中添加一行: Scrapy提供5层logging级别: CRITICAL - ...

  3. Xposed框架Hook Android应用的所有类方法打印Log日志

    本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80954759 在进行Android程序的逆向分析的时候,经常需要Android程 ...

  4. Atitit.log日志技术的最佳实践attilax总结

    Atitit.log日志技术的最佳实践attilax总结 1. 日志的意义与作用1 1.1. 日志系统是一种不可或缺的单元测试,跟踪调试工具1 2. 俩种实现[1]日志系统作为一种服务进程存在 [2] ...

  5. 解读ASP.NET 5 & MVC6系列(9):日志框架

    框架介绍 在之前的.NET中,微软还没有提供过像样的日志框架,目前能用的一些框架比如Log4Net.NLog.CommonLogging使用起来多多少少都有些费劲,和java的SLF4J根本无法相比. ...

  6. Java日志框架:SLF4J,Common-Logging,Log4J,Logback说明

    Log4j  Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器.UNIX Syslog守护进程等 ...

  7. java日志框架slf4j与log4j

    日志记录自然是非常重要的,但恐怕能记住slf4j与log4j等日志框架配置的人就很少了,这个东西不难,只是配置好后很少会去动它,开发新项目一般也是从其他项目拷贝,或者参照文档 废话不多说,先说log4 ...

  8. Moon转告给你一个比Log4net更好日志框架--TracerX Logger 及其对应的日志查看器

    一.介绍 TracerX logger是一个易于上手,且拥有众多高级特性的.NET日志框架. 它能够发送输出结果到多目的地(循环文件.事件日志等....).它也能生成文本和二进制文件.它拥有一个强大的 ...

  9. lombok+slf4j+logback SLF4J和Logback日志框架详解

    maven 包依赖 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lomb ...

随机推荐

  1. centos7单机版安装hbase

    1.首先安装jdk1.8 yum install java-1.8.0-openjdk* -y 2.下载hbase 地址:http://mirrors.shuosc.org/apache/hbase/ ...

  2. Sql Server分页分段查询百万级数据四种项目实例

    实际项目中需要实现自定义分页,最关键第一步就是写分页SQL语句,要求语句效率要高. 那么本文的一个查询示例是查询第100000-100050条记录,即每页50条的结果集.查询的表名为infoTab,且 ...

  3. iOS定位服务CoreLocation

    欢迎訪问我的新博客: 开发人员说 基于LBS的应用开发是当今移动开发中的一大热门, 当中主要涉及到地图和定位两个方面. iOS开发中, 定位服务依赖于CoreLocation框架, CLLocatio ...

  4. elasticsearch 使用快照方式迁移数据

    注册快照仓库 ES是通过快照的方式来实现数据备份,并且是以增量的方式,所以一般第一次做的话会花费较长的时间.为了做快照,那么就需要注册一个快照仓库,告诉ES我们的快照应该如何保存以及将快照保存到哪里. ...

  5. Linux学习之tune2fs

    这是Linux系统用于文件系统自检的工具. 常用选项 -l 查看文件系统信息 -c max-mount-counts 设置强制自检的挂载次数,如果开启,每挂载一次mount conut就会加1,超过次 ...

  6. LNMP平滑升级nginx并安装ngx_lua模块教程

    #ngx_lua module项目地址 https://github.com/chaoslawful/lua-nginx-module 在LNMP安装包后,重编译nginx,并添加ngx_lua模块 ...

  7. iOS 全屏播放网页视频退出后状态栏被隐藏

    使用wkWebView播放网页上的视频,播放完成后,退出视频返回到网页发现app的状态整个被隐藏了,解决方法,监听状态栏隐藏通知,在适当的时候让状态栏显示出来 [[NSNotificationCent ...

  8. zabbix 监控如下内容

    我们使用zabbix做了如下的监控: 1.硬件监控. 通过SNMP来进行路由器交换机的监控(这些可以跟一些厂商沟通来了解如何做). 服务器的温度以及其他,可以通过IPMI来实现.当然如果没有硬件全都是 ...

  9. jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、

    脚 本 之 家 www.jb51.net 脚本云 专题 素材下载 电子书 软件下载 源码下载 服务器常用软件 a5交易 首页 网页制作 脚本专栏 脚本下载 网络编程 数据库 CMS教程 电子书籍 平面 ...

  10. MySQL - 统计每个月生日的人数

    Person表定义如下: create table person(id int primary key auto_increment, birthday datetime); Person 数据如下: ...