1. 前言

  从写代码开始,就陆陆续续接触到了许多日志框架,较常用的属于LOG4J,LogBack等。每次自己写项目时,就copy前人的代码或网上的demo。配置log4j.properties或者logback.properties就能搞定。这种思想一直持续到最近,前几天写了一个小demo,放在liunx上跑的时候竟然报stackOverFlow异常,仔细看异常信息,log4j-over-slf4j与slf4j-log4j12共存导致stack overflow异常,这一刻终于来了,我不得不去正式日志框架了。

2. 解决方案

  先贴一下我的解决方案。既然报冲突了,不管三七二十一,先删除一个jar包就OK!第一种解决方案直接在项目的WEB-INF\lib下删除slf4j-log4j12.jar包。

cd /WEB-INF/lib
rm -rf slf4j-log4j12-1.7..jar

  这种方案只是临时方案,再次打包部署时还会出现此问题。第二种方案是在pom.xml找到引用此JAR包的地方,我是因为引入了zookeeper,自带了此JAR包。使用<exclusion>标签排除此JAR包。或者使用<packagingExcludes>标签在打包时排除此JAR包。个人推荐使用<packagingExcludes>,因为我的<exclusion>标签不管用,此处不做详解,直接贴代码!

<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>WEB-INF/lib/slf4j-log4j12-1.7.25.jar</packagingExcludes>
</configuration>
</plugin>

3. 基本日志框架之间关系

  类比java的面向接口编程思想,JAVA日志框架分为接口层,实现层,还多了个桥接层,桥接层联系接口层和实现层。

  

  接口层:SELF4J,COMMONS-LOGGING

  实现层:LOG4J,LOGBACK,JDK-LOOGING,LOG4J2

  以上为通用的日志框架实现(即实现)和门面(即接口)。日志门面的出现很大程度缓解了日志系统的混乱,很多库的作者不在使用具体的日志框架实现了,而是去使用接口层,即面向接口编程。此处,贴一段话,方面更能理解。

  应用程序直接使用这些具体日志框架的API来满足日志输出需求当然是可以的,但是由于各个日志框架之间的API通常是不兼容的,这样做就使得应用程序丧失了更换日志框架的灵活性。比直接使用具体日志框架API更合理的选择是使用日志门面接口。日志门面接口提供了一套独立于具体日志框架实现的API,应用程序通过使用这些独立的API就能够实现与具体日志框架的解耦,这跟JDBC是类似的。最早的日志门面接口是commons-logging,但目前最受欢迎的是slf4j。日志门面接口本身通常并没有实际的日志输出能力,它底层还是需要去调用具体的日志框架API的,也就是实际上它需要跟具体的日志框架结合使用。由于具体日志框架比较多,而且互相也大都不兼容,日志门面接口要想实现与任意日志框架结合可能需要对应的桥接器,就好像JDBC与各种不同的数据库之间的结合需要对应的JDBC驱动一样。

4. StackOverFlow异常分析

  

  上图来自SLF4J官网。如图,上层都是使用SLF4JAPI对外暴露接口。SLF4JAPI使用的是slf4j-api.jar包。接着下层各个日志框架的实现就不一样了,最左边的是slf4j的一个空实现。第二列和第五列是logback和slf4j的一个简单实现,这2个框架没有使用所谓的桥接器,直接继承slf4j,实现slf4j的接口。log4j和jul的实现是要依靠桥接器,如上,slf4j-log412.jar和slf4j-jdk14.jar就是桥接器,分别连接slf4j,log4j和slf4j,jul。下面的log4j.jar和JVM runtime便是具体实现。

  其他日志系统转掉回slf4j,如果只存在slf-4j转到日志系统实现类,便不会存在StackOverFlow的异常。如果我们使用log4j日志系统,但又想使用别的日志系统,此时就要使用从日志系统到slf4j的桥接类 log4j-over-slf4j,这个库定义了与log4j一致的接口(包名、类名、方法签名均一致),但是接口的实现却是对slf4j日志接口的包装,即间接调用了slf4j日志接口,实现了对日志的转发。

  既然存在这么多桥接器,万一我的系统中存在slf4j -> log4j 和 log4j -> slf4j的桥接器。。。。就会出现互相委托,无限循环,堆栈溢出的状况。所有就会有出现异常。slf4j关于桥接器的详细介绍参考slf4j官方网站:https://www.slf4j.org/legacy.html

  比如,我现在想使用slf4j的实现类logback日志框架

  1. 引入slf4j & logback日志包和slf4j -> logback桥接器;

  2. 排除common-logging、log4j、log4j2日志包;

  3. 引入jdk-logging -> slf4j、common-logging -> slf4j、log4j -> slf4j、log4j2 -> slf4j桥接器;

  4. 排除slf4j -> jdk-logging、slf4j -> common-logging、slf4j -> log4j、slf4j -> log4j2桥接器。

 

  

Java日志框架总结的更多相关文章

  1. Java程序员最常用的8个Java日志框架

    转自:http://www.codeceo.com/article/8-java-log-framework.html 作为一名Java程序员,我们开发了很多Java应用程序,包括桌面应用.WEB应用 ...

  2. 转:Java程序员最常用的8个Java日志框架

    作为一名Java程序员,我们开发了很多Java应用程序,包括桌面应用.WEB应用以及移动应用.然而日志系统是一个成熟Java应用所必不可少的,在开发和调试阶段,日志可以帮助我们更好更快地定位bug:在 ...

  3. Java 日志框架终极教程

    概述 对于现代的 Java 应用程序来说,只要被部署到真实的生产环境,其日志的重要性就是不言而喻的,很难想象没有任何日志记录功能的应用程序被运行于生产环境中.日志 API 所能提供的功能是多种多样的, ...

  4. Java日志框架那些事儿

    文章首发于[博客园-陈树义],点击跳转到原文Java日志框架那些事儿. 在项目开发过程中,我们可以通过 debug 查找问题.而在线上环境我们查找问题只能通过打印日志的方式查找问题.因此对于一个项目而 ...

  5. Java基础学习总结(40)——Java程序员最常用的8个Java日志框架

    作为一名Java程序员,我们开发了很多Java应用程序,包括桌面应用.WEB应用以及移动应用.然而日志系统是一个成熟Java应用所必不可少的,在开发和调试阶段,日志可以帮助我们更好更快地定位bug:在 ...

  6. Java-最常用的Java日志框架整理

    Java-最常用的Java日志框架整理 前言 Java程序员,我们开发了很多Java应用程序,包括桌面应用.WEB应用以及移动应用.然而日志系统是一个成熟Java应用所必不可少的,在开发和调试阶段,日 ...

  7. java日志框架系列(4):logback框架xml配置文件语法

    1.xml配置文件语法 由于logback配置文件语法特别灵活,因此无法用DTD或schema进行定义. 1.配置文件基本结构 配置文件基本结构:以<configuration>标签开头, ...

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

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

  9. java日志框架slf4j与log4j

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

随机推荐

  1. 自定义ItemToggleView

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...

  2. 7.源码分析---SOFARPC是如何实现故障剔除的?

    我在服务端引用那篇文章里面分析到,服务端在引用的时候会去获取服务端可用的服务,并进行心跳,维护一个可用的集合. 所以我们从客户端初始化这部分说起. 服务连接的维护 客户端初始化的时候会调用cluste ...

  3. Java学习多线程第一天

    内容介绍 Thread 线程创建 线程池 线程状态图 1 多线程 1.1     多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序 ...

  4. charles(version4.2.1)抓包手机数据

    点击菜单栏的Proxy项,选择Proxy Settings. 设置HTTP Proxy的Port. 勾选透明代理Enable transparent HTTP proxying,也可不勾选. 设置代理 ...

  5. [转载]关于ActiveMQ集群

    转载于 http://blog.csdn.net/nimmy/article/details/6247289 近日因工作关系,在研究JMS,使用ActiveMQ作为提供者,考虑到消息的重要,拟采用Ac ...

  6. 编程使用c#连接到IBM db2的两种方式

    一:使用c#通过odbc连接到IBM db2使用 ConnectionString 属性连接到各种数据源. 部署:只要在客户端安装IBM DB2 ODBC driver.配置DSn即可. 1):可以单 ...

  7. Spring Cloud与Dubbo的完美融合之手「Spring Cloud Alibaba」

    很早以前,在刚开始搞Spring Cloud基础教程的时候,写过这样一篇文章:<微服务架构的基础框架选择:Spring Cloud还是Dubbo?>,可能不少读者也都看过.之后也就一直有关 ...

  8. 登录cookies

    cookie Cookie 是指某些网站服务器为了辨别用户身份和进行Session跟踪,而储存在用户浏览器上的文本文件,Cookie可以保持登录信息到用户下次与服务器的会话./p> cookie ...

  9. Zabbix添加windows主机监控

    zabbix监控windows主机 1.官网下载zabbix的windows-agent(选择相应版本): https://www.zabbix.com/cn/download_agents 2.将下 ...

  10. copy and mutableCopy

    结论: 1, 深复制与浅复制 2,immutable和mutable 3,代码分析: #pragma mark - String - (void)stringCopyAndMutableCopy { ...