Could not initialize class org.apache.log4j.Log4

(一) 現象與解決方法

前些天在進行storm job的開發時候忽然報了一個錯誤,記錄一下html

Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.log4j.Log4jLoggerFactory

固然咱們的第一個反應是log4j這個包缺失(固然也有這種狀況,須要首先確認),打開pom文件查看依賴,文件確實存在。java

後經網上搜索加邊上大牛指點發現:數據庫

log4j-over-slf4j.jar 和 slf4j-log4j12.jar 在同一個classpath下就會出現這個錯誤。apache

解決方法: 
將slf4j-log4j12.jar從相關的jar中排除工具

(二) 日誌組件tips

那麼問題來了,爲啥會有這種衝突呢?在這裏須要簡單的說一下log的故事!spa

(1)common-logging、log4j、slf4j、logback.net

common-logging 
common-logging是apache提供的一個通用的日誌接口;開放源代碼

在common-logging中,有一個Simple logger的簡單實現,可是它功能很弱,因此使用common-logging,一般都是配合着log4j來使用;設計

common-logging會經過動態查找的機制,在程序運行時自動找出真正使用的日誌庫,而且儘量找到一個」最合適」的日誌實現類,若是判斷有Log4j包,則使用log4j,最悲觀的狀況下也總能保證提供一個日誌實現(SimpleLog)日誌

log4j 
Apache的一個開放源代碼項目,實現了輸出到控制檯、文件、 回滾文件、發送日誌郵件、輸出到數據庫日誌表、自定義標籤等全套功能,且配置比較簡單;

slf4j 
slf4J,即簡單日誌門面(Simple Logging Facade for Java),不是具體的日誌解決方案,它只服務於各類各樣的日誌系統。按照官方的說法,SLF4J是一個用於日誌系統的簡單Facade,容許最終用戶在部署其應用時使用其所但願的日誌系統。能夠這麼說,slf4j等於commons-logging,是各類日誌實現的通用入口,會根據classpath中存在下面哪個Jar來決定具體的日誌實現庫;

logback 
logback是由log4j創始人設計的又一個開源日誌組件。logback當前分紅三個模塊:logback-core,logback- classic和logback-access。logback-core是其它兩個模塊的基礎模塊。logback-classic是log4j的一個 改良版本。此外logback-classic完整實現SLF4J API使你能夠很方便地更換成其它日誌系統如log4j。

(2)log4j-over-slf4j.jar 和 slf4j-log4j12.jar 在同一個classpath下爲什麼出現錯誤?

在java領域日誌工具中,最先獲得普遍使用的是 log4j。那麼爲啥有common-logging的出現?上面已經介紹了common-logging只提供log的接口,其中具體的實現時動態綁定的,因此common-logging與log4j的結合比較多!可是隨之也產生了一些問題,那就是common-logging的動態綁定有時候也會失敗(說實在這個我也不懂,但願求解),在這樣的背景下slf4j應運而生,slf4j與common-logging同樣提供log接口,可是slf4j是經過靜態綁定實現。

好的,先在來講slf4j-log4j12.jar是幹啥的? 
slf4j提供 log 接口,其具體實現是根據放入程序的綁定器決定

slf4j-XXX-version.jar

slf4j-log4j12.jar就是實現經過slf4j調度使用log4j

那麼log4j-over-slf4j.jar是幹啥的勒?

在這裏須要引入橋接器的概念,所謂的橋接器就是一個假的日誌實現工具。

XXX-over-slf4j.jar

log4j-over-slf4j.jar就是橋接器,原本組件是經過log4j輸出日誌的,經過該橋接器被轉到slf4j,slf4j在根據綁器把日誌交給具體的日誌實現工具。

若是log4j-over-slf4j.jar 和 slf4j-log4j12.jar共存的後果是什麼?那就是兩個踢球的人在互相傳球,就是沒人射門,陷入死循環。

這裏寫圖片描述

參考博文:  [1]http://blog.csdn.net/feng27156/article/details/36885387  [2]http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html

相關文章
相關標籤/搜索