HDFS編程實戰中出現的問題

問題來源:慕課網——廈門大學林子雨老師主講《大數據技術原理與應用》——3.6-HDFS編程實戰

系統環境:

  • ubuntu 14.04 LTS
  • Hadoop 2.7.6
  • Eclipse 3.8.1
  • javaSE-1.7

補充:系統環境的搭配參考:http://dblab.xmu.edu.cn/blog/install-hadoop/

編程前——按視頻教程中的配置

  1. 打開Eclipse創建項目HadTest(項目名自取)
  2. 導入jar包hadoop-common-2.7.6.jar(jar包位於/usr/local/hadoop/share/hadoop/common/)
  3. 將core-site.xml與hdfs-site.xml複製到項目HadTest下的bin文件下(*.xml文件位於/usr/local/hadoop/etc/hadoop/)
  4. 編寫代碼

編寫代碼後運行:

問題1——Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory

異常顯示沒有發現類org.apache.commons.logging.LogFactory,分析爲jar包缺失,在/usr/local/hadoop/share/hadoop/common/lib/下找到jar包commons-logging-1.1.3.jar導入後,該問題解決

上面問題解決後接着運行程序:

問題2——Caused by: java.lang.ClassNotFoundException: com.google.common.base.Preconditions

異常顯示沒有發現類com.google.common.base.Preconditions,分析爲jar包缺失,在/usr/local/hadoop/share/hadoop/common/lib/下找到jar包guava-11.0.2.jar導入後,該問題解決

繼續運行程序:

問題3——Caused by: java.lang.ClassNotFoundException: org.apache.commons.collections.map.UnmodifiableMap

異常顯示沒有發現類org.apache.commons.collections.map.UnmodifiableMap,分析爲jar包缺失,在/usr/local/hadoop/share/hadoop/common/lib/下找到jar包commons-collections-3.2.2.jarr導入後,該問題解決

問題4——Caused by: java.lang.ClassNotFoundException: org.apache.commons.configuration.Configuration

異常顯示沒有發現類org.apache.commons.configuration.Configuration,分析爲jar包缺失,在/usr/local/hadoop/share/hadoop/common/lib/下找到jar包commons-configuration-1.6.jar導入後,該問題解決

問題5——Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang.StringUtils

解決:導入/usr/local/hadoop/share/hadoop/common/lib/commons-lang-2.6.jar,該問題解決

問題6——Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.util.PlatformName

解決:導入/usr/local/hadoop/share/hadoop/common/lib/hadoop-auth-2.7.6.jar,該問題解決

問題7——Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory

解決:導入/usr/local/hadoop/share/hadoop/common/lib/slf4j-api-1.7.10.jar,該問題解決


問題8——java.io.IOException: No FileSystem for scheme: hdfs

問題具體描述:

可以看出異常出現在第13行代碼:FileSystem fs=FileSystem.get(configuration)。與FileSystem類中的get方法有關,該類位於jar包hadoop-common-2.7.6.jar中。在linux操作系統中用歸檔管理器打開該jar包,可以看到對應的.class文件

用Eclipse反編譯該jar包以查看源碼,具體添加插件可以參考下面這篇博客

插件安裝完成後,常按住Ctrl鍵,然後點擊 類 || 接口 || 方法(FileSystem.get()) 名,即可進入源碼

繼續分析異常爲java.io.IOException: No FileSystem for scheme: hdfs。以IOException爲目標一個方法一個方法點進去看

最後是在這裏發現了熟悉的東西:No FileSystem for scheme: hdfs

分析:拋出No FileSystem for scheme: hdfs異常語句的原因是clazz爲null,該方法的目的是反射加載類。

第一步:loadFileSystems();

裝填HashMap容器SERVICE_FILE_SYSTEMS,該方法只執行一次

第二步:clazz = conf.getClass("fs." + scheme + ".impl", null);

看註釋可以知道,該方法可以根據name獲取對應的Class對象,該對象應該是作爲了一個屬性值與成映射關係,如果沒有該name屬性,即返回defaultValue,在上一個方法中即返回null

第三步:clazz = (Class) SERVICE_FILE_SYSTEMS.get(scheme);

由此可以分析出,clazz一直爲空,在第二步也就是配置文件中沒有找到屬性爲fs.hdfs.impl的配置,且在第一步裝填容器中也沒有存在key爲hdfs的映射關係

於是有了一個初步的解決方案:1、找到配置文件,在裏面加上fs.hdfs.impl配置;2、繼續研究loadFileSystems(),找到將hdfs映射關係寫入Map容器中的方法。

之後我直接將fs.hdfs.impl複製到百度去搜索,篩選到這篇博客hadoop三個配置文件的參數含義說明

知道了配置文件名爲core-default.xml,fs.hdfs.impl映射值爲org.apache.hadoop.hdfs.DistributedFileSystem

接下來就要找到core-default.xml,然後將映射關係寫進去

因爲不知道配置文件的具體路徑,直接在usr/local/hadoop/下搜索core-default.xml

發現有兩個一模一樣的文件,那就一個一個的試吧

運行,發現還是老樣子,貌似修改這兩個配置文件沒有任何毛用,想起前段時間自己做的jar可執行程序,配置文件保存位置有兩種選擇,一是不與程序一起打包(即放在jar包外),另一種是和程序一起打包(即在jar包內部),所以我再次用linux中的歸檔管理器打開hadoop-common-2.7.6.jar

嗯!發現了,這裏有一個配置文件,盤他。

完成後,再次運行程序!!!


問題9——Caused by: java.lang.ClassNotFoundException: Class org.apache.hadoop.hdfs.DistributedFileSystem not found

解決:導入/usr/local/hadoop/share/hadoop/common/lib/jackson-mapper-asl-1.9.13.jar
/usr/local/hadoop/share/hadoop/common/lib/htrace-core-3.1.0-incubating.jar
/usr/local/hadoop/share/hadoop/common/lib/commons-cli-1.2.jar
/usr/local/hadoop/share/hadoop/common/lib/protobuf-java-2.5.0.jar
/usr/local/hadoop/share/hadoop/common/lib/commons-io-2.4.jar
/usr/local/hadoop/share/hadoop/hdfs/hadoop-hdfs-2.7.6.jar這些包

最後的程序雖然有了輸出,但還是有一個異常,我看了該類,明明在jar包中且該jar包已經導入了項目,這就不是我理解的了


所以我最後的解決方案是:將/usr/local/hadoop/share/hadoop/common/lib/下的所有jar包,/usr/local/hadoop/share/hadoop/common/下的三個jar包,/usr/local/hadoop/share/hadoop/hdfs/下的hadoop-hdfs-2.7.6.jar一起導入到項目中,然後運行項目

。。。。。。。。。。。。。

總結:這是我學習大數據技術的第一個編程實踐,很曲折,明明是按照視頻教學裏的步驟來的,結果還是各種錯,雖然最後以空間(導入所有的jar包)換取了正解,但中間對異常的分析思路是自己在找bug技術上的一次突破。回去看看,其實這個實踐的重點在第8個問題中,至於爲什麼視頻教學裏老師只導入一個jar包就可以正常執行程序,而我需要導入所有的jar包纔行,這個問題我也沒有找到答案,可能是視頻中的某些細節我沒有注意到吧,有時間再回去看看!也希望有機會看到這篇博文的朋友能提點一下。

感謝這些博主:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章