成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Log4j2 在 Windows 下導(dǎo)致 System.out 失效

Harpsichord1207 / 3643人閱讀

摘要:此問題已經(jīng)在里面修復(fù),詳見今天在下調(diào)試這幾天寫的一個(gè)命令行程序,發(fā)現(xiàn)在在一種情況下會(huì)在下會(huì)出現(xiàn)無法輸出到終端的情況,花了幾個(gè)小時(shí)去排查這個(gè)問題,這里分享一下。

  

此問題已經(jīng)在 Log4j2 2.3 里面修復(fù),詳見 https://issues.apache.org/jira/browse/LOG4J2-965

今天在 Windows 下調(diào)試這幾天寫的一個(gè)命令行程序,發(fā)現(xiàn)在 Log4j2 在一種情況下會(huì)在 Windows 下會(huì)出現(xiàn) System.out.println("XXXX") 無法輸出到終端的情況,花了幾個(gè)小時(shí)去排查這個(gè)問題,這里分享一下。

1. 問題還原

為了簡(jiǎn)化問題,我盡量用少的代碼來重現(xiàn)出這個(gè) Bug,首先是工程的 build.gradle 文件:

apply plugin: "java"

version = "1.0"

repositories {
    mavenCentral()
}

def log4j2Version = "2.2"
def log4j2GroupId = "org.apache.logging.log4j"

dependencies {
    compile log4j2GroupId + ":log4j-core:" + log4j2Version
    compile log4j2GroupId + ":log4j-jcl:" + log4j2Version
    compile log4j2GroupId + ":log4j-slf4j-impl:" + log4j2Version
    compile "org.fusesource.jansi:jansi:1.11"
}

一個(gè)位于 src/main/resources 目錄下的 log4j2.xml



    
        
            
                %d %p %c{1.} [%t] %m%n
            
        
    
    
        
            
        
    

然后是重現(xiàn)問題的代碼:

import org.slf4j.LoggerFactory;

/**
 * @author khotyn 15/3/2 下午8:17
 */
public class Log4j2WindowsBug {

    public static void main(String[] args) {
        System.out.println("Able to print on Windows");
        LoggerFactory.getLogger(Log4j2WindowsBug.class);
        System.out.println("Unable to print on Windows");
    }
}

這段代碼在 Windows 下的運(yùn)行結(jié)果是:

Able to print on Windows

getLogger 后面的那一句 System.out 并沒有輸出。

2. 問題原因

剛開始遇到這個(gè)問題的時(shí)候非常震驚,因?yàn)橛X得 System.out.println 應(yīng)該是 Java 最基本的功能了,遇到這樣的問題,瞬間讓我覺得人生完整了。在經(jīng)過一陣 Debug 以后,發(fā)現(xiàn)執(zhí)行第三行代碼的時(shí)候,System.out 這個(gè) PrintWriter里面的 out 成員變量為 null 了,然后就導(dǎo)致了 println 方法在檢查 out 是否為 null 的時(shí)候拋了一個(gè)異常:

/** Checks to make sure that the stream has not been closed */
private void ensureOpen() throws IOException {
    if (out == null)
        throw new IOException("Stream closed");
}

那么到底是什么把 out 給置為 null 了呢。經(jīng)過了一段時(shí)間的 Debug,發(fā)現(xiàn)了在 Windows 下,如果 ClassPath 下有 org.fusesource.jansi.WindowsAnsiOutputStream 這個(gè)類的話,Log4j2 會(huì)將用這個(gè)類將 System.out 包裝起來(按照 Log4j2 的說明,這是是為了在 Windows 下的 Console 上支持彩色字符):

然后,在 log4j2 里面,不管在 ClassPath 下有沒有 log4j2.xml 或者方式的配置,它都會(huì)先初始化一個(gè) ConsoleAppender,如果后面發(fā)現(xiàn)有諸如 log4j2.xml 這樣的配置,那么就進(jìn)行 reconfigure,我們看下 log4j2 里面的 LoggerContext 類的 reconfigure 方法:

主要看它所調(diào)用到的 setConfiguration 方法:

在這個(gè)方法里面,如果發(fā)現(xiàn)之前有了配置(就是默認(rèn)的 ConsoleAppender),就會(huì)嘗試關(guān)閉它,然后繼續(xù)跟蹤 prev.stop 這段代碼,發(fā)現(xiàn)它下面會(huì)走到 OutPutStreamManager 的這段代碼:

只有當(dāng) outputStream 是 System.out 或者 System.err 的時(shí)候,才不會(huì)關(guān)閉,但是如果是 System.out 的封裝,就比如我們這個(gè)場(chǎng)景中的 WindowsAnsiOutputStream,就被關(guān)閉了,進(jìn)而導(dǎo)致后續(xù)的 System.out.println 都無效。

3. 解決方法

其實(shí)細(xì)心的話,在上面的截圖的代碼中就可以看到解決方法了,要解決這個(gè)問題,只需要在 log4j2 初始化之前執(zhí)行下面這段代碼

System.setProperty("log4j.skipJansi", true)

不過,這個(gè)方法只有像我這樣其實(shí)對(duì)于 log4j 時(shí)候采用 Jansi 的封裝無所謂的人才算有用。如果有所謂的話,那么似乎只能坐等官方修 Bug 了(https://issues.apache.org/jira/browse/LOG4J2-965)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64252.html

相關(guān)文章

  • log4j2搭建并使用

    摘要:作為一個(gè)實(shí)用主義者,我喜歡在理解基本原理后快速的搭建系統(tǒng),當(dāng)系統(tǒng)運(yùn)行起的時(shí)候有那種愉悅和興奮。,著手搭建,我用的是進(jìn)行的。要使用日志系統(tǒng),就需要進(jìn)行相關(guān)配置,這個(gè)不用我多說了叁。 作為一個(gè)實(shí)用主義者,我喜歡在理解基本原理后快速的搭建系統(tǒng),當(dāng)系統(tǒng)運(yùn)行起的時(shí)候有那種愉悅和興奮。最近在完善公司框架,從最基本的日志系統(tǒng)開始。 java日志系統(tǒng)比較流行的是log4j,slf4j和logbac...

    lauren_liuling 評(píng)論0 收藏0
  • java判斷百度云分享鏈接是否失效

    我不知道現(xiàn)在有多少人在用網(wǎng)盤搜索引擎,但就去轉(zhuǎn)盤網(wǎng)來說本人傾注了很多的心血,現(xiàn)在使用的人數(shù)也還可以,網(wǎng)盤資源都有個(gè)通病,那就是資源可能失效,但很多引擎都沒有做失效判斷,尤其是一些google自定義的引擎,技術(shù)含量不高,站長(zhǎng)也就花心思賺錢,很少考慮用戶體驗(yàn)。這篇文章是本人又一篇技術(shù)公開博客,之前本人已經(jīng)公開了去轉(zhuǎn)盤 網(wǎng)的幾乎所有的技術(shù)細(xì)節(jié),這一篇繼續(xù)補(bǔ)充: 首先做個(gè)回顧:百度網(wǎng)盤爬蟲 java分詞...

    kid143 評(píng)論0 收藏0
  • java判斷百度云分享鏈接是否失效

    我不知道現(xiàn)在有多少人在用網(wǎng)盤搜索引擎,但就去轉(zhuǎn)盤網(wǎng)來說本人傾注了很多的心血,現(xiàn)在使用的人數(shù)也還可以,網(wǎng)盤資源都有個(gè)通病,那就是資源可能失效,但很多引擎都沒有做失效判斷,尤其是一些google自定義的引擎,技術(shù)含量不高,站長(zhǎng)也就花心思賺錢,很少考慮用戶體驗(yàn)。這篇文章是本人又一篇技術(shù)公開博客,之前本人已經(jīng)公開了去轉(zhuǎn)盤 網(wǎng)的幾乎所有的技術(shù)細(xì)節(jié),這一篇繼續(xù)補(bǔ)充: 首先做個(gè)回顧:百度網(wǎng)盤爬蟲 java分詞...

    chanthuang 評(píng)論0 收藏0
  • SpringBoot(三)日志

    摘要:日志消息,是換行符如果使用作為日志配置文件,還要使用功能,會(huì)有以下錯(cuò)誤切換日志框架可以按照的日志適配圖,進(jìn)行相關(guān)的切換的方式切換為 三、日志 1、日志框架 小張;開發(fā)一個(gè)大型系統(tǒng); 1、System.out.println();將關(guān)鍵數(shù)據(jù)打印在控制臺(tái);去掉?寫在一個(gè)文件? 2、框架來記錄系統(tǒng)的一些運(yùn)行時(shí)信息;日志框架 ; zhanglogging.jar; 3、高大上的幾個(gè)功能?異步...

    arashicage 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<