log日志框架和LocationAwareLogger问题
遇到了同样的问题,
我的解决办法是在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代码
- package com.taobao.wuzhong.log;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.junit.Test;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- /**
- * DESC:
- *
- * Copyright: Copyright 2011 m.taobao.com
- *
- * @author wuzhong@taobao.com
- * @time 2011-4-6 下午03:42:11
- * @version 1.0
- **/
- public class LogTest {
- // Logback tries to find a file called logback.groovy in the classpath.
- // If no such file is found, logback tries to find a file called
- // logback-test.xml in the classpath.
- // If no such file is found, it checks for the file logback.xml in the
- // classpath..
- // If neither file is found, logback configures itself automatically using
- // the BasicConfigurator which will cause logging output to be directed to
- // the console.
- @Test
- public void test() {
- //commons-logging的方式获取
- Log log = LogFactory.getLog(LogTest.class);
- //slf4j直接的方式获取,推荐用这个
- Logger log2 = LoggerFactory.getLogger(LogTest.class);
- log.debug("eeeeee {} {} {}");
- log2.debug("{} {} {}", new String[] { "a", "b", "c" });
- }
- }
logFactory.getLog 会调用内部静态变量 Slf4jLogFactory.getInstance方法,如下:
public Log getInstance(String name) throws LogConfigurationException {
- Log instance = null;
- // protect against concurrent access of loggerMap
- synchronized (this) {
- instance = (Log) loggerMap.get(name);
- if (instance == null) {
- Logger logger = LoggerFactory.getLogger(name); //slf4j的方式,代理过去了
- if(logger instanceof LocationAwareLogger) {
- instance = new SLF4JLocationAwareLog((LocationAwareLogger) logger); //包装了一层,做适配
- } else {
- instance = new SLF4JLog(logger);
- }
- loggerMap.put(name, instance);
- }
- }
- return (instance);
loggerFactory 会调用getILoggerFactory().getlOgger()
- LoggerFactory.java
- public static ILoggerFactory getILoggerFactory() {
- if (INITIALIZATION_STATE == UNINITIALIZED) {
- INITIALIZATION_STATE = ONGOING_INITILIZATION;
- performInitialization();
- }
- switch (INITIALIZATION_STATE) {
- case SUCCESSFUL_INITILIZATION:
- return getSingleton().getLoggerFactory();
- case FAILED_INITILIZATION:
- throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
- case ONGOING_INITILIZATION:
- // support re-entrant behavior.
- // See also http://bugzilla.slf4j.org/show_bug.cgi?id=106
- return TEMP_FACTORY;
- }
- throw new IllegalStateException("Unreachable code");
- }
- private final static void performInitialization() {
- bind();
- versionSanityCheck();
- singleImplementationSanityCheck();
- }
这里的bind很关键,这里动态的绑定了slf4j-api的实现机制
- static {
- SINGLETON.init();
- }
- /**
- * Package access for testing purposes.
- */
- void init() {
- try {
- try {
- new ContextInitializer(defaultLoggerContext).autoConfig();
- } catch (JoranException je) {
- Util.reportFailure("Failed to auto configure default logger context",
- je);
- }
- StatusPrinter.printInCaseOfErrorsOrWarnings(defaultLoggerContext);
- contextSelectorBinder.init(defaultLoggerContext, KEY);
- initialized = true;
- } catch (Throwable t) {
- // we should never get here
- Util.reportFailure("Failed to instantiate ["
- + LoggerContext.class.getName() + "]", t);
- }
- }
获取配置信息初始化
- autoConfig ….
- public URL findURLOfDefaultConfigurationFile(boolean updateStatus) {
- ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);
- URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus);
- if (url != null) {
- return url;
- }
- url = Loader.getResource(TEST_AUTOCONFIG_FILE, myClassLoader);
- if (updateStatus) {
- statusOnResourceSearch(TEST_AUTOCONFIG_FILE, myClassLoader, url);
- }
- if (url != null) {
- return url;
- }
- url = Loader.getResource(AUTOCONFIG_FILE, myClassLoader);
- if (updateStatus) {
- statusOnResourceSearch(AUTOCONFIG_FILE, myClassLoader, url);
- }
- return url;
- }
- public void autoConfig() throws JoranException {
- StatusListenerConfigHelper.installIfAsked(loggerContext);
- URL url = findURLOfDefaultConfigurationFile(true);
- if (url != null) {
- configureByResource(url);
- } else {
- BasicConfigurator.configure(loggerContext);
- }
- }
最后画张流程图总结下,^_^

总结: 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问题的更多相关文章
- Spring Boot Log 日志使用教程
我们编写任何 Spring Boot 程序,可能绕不开的就是 log 日志框架(组件). 在大多数程序员眼中日志是用来定位问题的.这很重要. 本项目源码下载 注意本项目提供的源码已在后期重新编写,有部 ...
- scrapy框架之log日志
scrapy中的debug信息 在scrapy中设置log 1.在settings中设置log级别,在settings.py中添加一行: Scrapy提供5层logging级别: CRITICAL - ...
- Xposed框架Hook Android应用的所有类方法打印Log日志
本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80954759 在进行Android程序的逆向分析的时候,经常需要Android程 ...
- Atitit.log日志技术的最佳实践attilax总结
Atitit.log日志技术的最佳实践attilax总结 1. 日志的意义与作用1 1.1. 日志系统是一种不可或缺的单元测试,跟踪调试工具1 2. 俩种实现[1]日志系统作为一种服务进程存在 [2] ...
- 解读ASP.NET 5 & MVC6系列(9):日志框架
框架介绍 在之前的.NET中,微软还没有提供过像样的日志框架,目前能用的一些框架比如Log4Net.NLog.CommonLogging使用起来多多少少都有些费劲,和java的SLF4J根本无法相比. ...
- Java日志框架:SLF4J,Common-Logging,Log4J,Logback说明
Log4j Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器.UNIX Syslog守护进程等 ...
- java日志框架slf4j与log4j
日志记录自然是非常重要的,但恐怕能记住slf4j与log4j等日志框架配置的人就很少了,这个东西不难,只是配置好后很少会去动它,开发新项目一般也是从其他项目拷贝,或者参照文档 废话不多说,先说log4 ...
- Moon转告给你一个比Log4net更好日志框架--TracerX Logger 及其对应的日志查看器
一.介绍 TracerX logger是一个易于上手,且拥有众多高级特性的.NET日志框架. 它能够发送输出结果到多目的地(循环文件.事件日志等....).它也能生成文本和二进制文件.它拥有一个强大的 ...
- lombok+slf4j+logback SLF4J和Logback日志框架详解
maven 包依赖 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lomb ...
随机推荐
- 压测过程中,CPU和内存占用率很高,案例简单分析
Q: 最近公司测试一个接口,数据库采用Mongo 并发策略:并发400个用户,每3秒加载5个用户,持续运行30分钟 数据量:8000条左右 压测结果发现: TPS始终在5左右 ...
- 用尽洪荒之力整理的Mysql数据库32条军规(转)
今天上午吐血整理了Oracle SQL性能优化的40条军规,其中很多规则也是适用于Mysql的,结果今晚发现这一篇文章——用尽洪荒之力整理的Mysql数据库32条军规,和我的竟有异曲同工之妙,当然不同 ...
- python challenge答案参考
Solutions to python challenge. http://garethrees.org/2007/05/07/python-challenge/ https://github.com ...
- SSH框架中POJO层, Dao层,Service层, Action层的功能理解
pojo层就是对应的数据库表的实体类(如User类). dao层,一般可以再分为***dao接口和***daoImpl实现类,如userDao接口和userDaoImpl实现类,接口负责定义数据库cu ...
- VS中 无法创建虚拟目录 本地IIS IIS Express 外部主机
从前就有个疑问了,为什么我拉取别人写好的代码后就可以在IIS里面生成一个网站呢? 这里所谓的生成网站,是指包含了所有源代码文件的网站:相对地,发布网站,就是指包含被编译的源文件所得到的DLL文件的网站 ...
- MySQL Memory 存储引擎浅析
原创文章,转载必需注明出处:http://www.cnblogs.com/wu-jian/ 前言 需求源自项目中的MemCache需求,開始想用MemCached(官方网站:http://memcac ...
- Log4Net 最最最基本的应用。作为个人记录
本文只记录了将日志按照日期记录到文件中的方法. 注:1.如果将该方法封装在类库中,在引用类库的项目中添加配置文件. 2.如果程序为控制台程序.winfrom程序,需将配置文件存放在/bin/debug ...
- CentOS7下利用init.d启动脚本实现tomcat开机自启动
在之前的博文中已经对CentOS7下通过tomcat进行WEB系统的发布进行了介绍,今天将利用init.d启动脚本,将服务脚本加入到开机启动服务队列,实现tomcat服务的开机启动. 1. 环境准备 ...
- iOS 提示更新 业务逻辑
1, 当程序启动,先去APPstore 检查有没有新版本.没有新版本就不提示,有新版本才提示. 2,只有当有提示了,再去判断是强制更新还是普通提示. 3,当后台给返回要强制更新时,就给出提示,并且没有 ...
- First MFC
// stdafx.h : include file for standard system include files, // or project specific include files t ...