最近在單機調試mapreduce程式到時候,由於代碼裡面有中文,我就將eclipse的編碼從預設到utf8調成了gbk,然後就發現原先可以運行到程式,現在不能運行了
java.io.IOException: Expecting a line not the end of stream
at org.apache.hadoop.fs.DF.parseExecResult(DF.java:109)
報錯資訊和下面到基本是一致的,解決辦法參見下面到解釋
http://hi.baidu.com/amdkings/blog/item/b589a5f56c1ddae17609d78f.html
系統是 ubuntu-10.04
IDE用的是eclipse
這時候出現了一個匪夷所思的現象,在終端中運行nutch,完全沒有任何問題。但是,一旦轉到eclipse下調試,nutch就跑不起來了,報出的錯誤如下:
java.io.IOException: Expecting a line not the end of stream
at org.apache.hadoop.fs.DF.parseExecResult(DF.java:109)
at org.apache.hadoop.util.Shell.runCommand(Shell.java:179)
at org.apache.hadoop.util.Shell.run(Shell.java:134)
at org.apache.hadoop.fs.DF.getAvailable(DF.java:73)
at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:321)
at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:124)
at org.apache.hadoop.mapred.MapOutputFile.getSpillFileForWrite(MapOutputFile.java:107)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:930)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.flush(MapTask.java:842)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:343)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:138)
在網上查了一通後,基本都是在windows下遇到這種問題,那是因為windows下沒有df命令。但是,我的是在ubuntu上發生的,這兩種情況不是一回事。
我跟蹤代碼到org.apache.hadoop.fs.DF.parseExecResult,觀察了此函數的傳入參數 BufferedReader lines, lines裡面顯示的內容是亂碼,但是確實是df正確執行後的結果。這時候,我有點明白了,本來是兩行的DF結果,由於亂碼,變成了一行,這才導致輸出上面的錯誤。
解決方案是:修改 DebugConfigurations,將commen選項頁中的console encoding ,設為 utf-8.以前的值是 Default-Inherited,由於我把項目預設編碼設成了gbk,所以此時的default就是 gbk
至此,真相大白: DF命令本身啟動並執行很正常,沒有出錯,不像網上的韓國和日本的有些人說是許可權問題導致DF失敗,只是這個結果被輸出到eclipse的console後,由於console的編碼設定問題,結果變質了,最終導致parseExecResult異常。
教訓慘痛,花費了整整一天的時間,看了中,日,韓和英幾種語言的二十多篇技術Blog。沒想到是自己擅自修改項目編碼帶來的問題。順便提一句,裝了cygwin後,我在windows系統下調試倒是一帆風順,沒有遇見這個問題.
不過還是想給hadoop項目的開發提點小建議,如果可能的話,最好重新設計一下DF和DF相關的類,爭取能自動識別命令結果的編碼格式,這樣就不會因為這種問題出錯。
項目初始的時候是在windows下開發,用的也是eclispe