MapReduce java.io.IOException: No FileSystem for scheme: d

一、 異常分析

最近, 在使用服務器運行 MapReduce 的 jar 包時報瞭如下錯誤:

[root@hadoop102 jars]# hadoop jar /opt/module/jars/mr-1.0-SNAPSHOT-jar-with-dependencies.jar com.atguigu.hive.project.gulivideo.ETLDriver /video/2008/0222 /gulivideo
Exception in thread "main" java.io.IOException: No FileSystem for scheme: d
	at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2644)
	at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2651)
	at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:92)
	at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2687)
	at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2669)
	at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:371)
	at org.apache.hadoop.fs.Path.getFileSystem(Path.java:295)
	at org.apache.hadoop.mapreduce.lib.input.FileInputFormat.setInputPaths(FileInputFormat.java:500)
	at com.atguigu.mr.wordcount.WordcountDriver.main(WordcountDriver.java:49)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
	at org.apache.hadoop.util.RunJar.main(RunJar.java:136)

由於我想要執行的是 com.atguigu.hive.project.gulivideo.ETLDriver 這個類, 但是我的 ETLDriver 類中並沒有指定 D 盤的代碼。

看報錯信息說是 FileInputFormat.setInputPaths 設置的時候出了錯, 可是代碼中是這麼設置的:

FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));

是從 args 參數中拿出來輸入路徑和輸出路徑。

試了很多方式也沒有解決掉, 所以犯了難。

最終還是找了大神請教了下, 原來我的 pom.xml 文件中, 之前的代碼留下了這樣的一段:

... ...
<descriptorRefs>
    <descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
    <manifest>
        <mainClass>com.atguigu.mr.wordcount.WordcountDriver</mainClass>
    </manifest>
</archive>
... ...

由於這個位置指定了一個 WordcountDriver 類, 導致使用 Maven 編譯的時候, 編譯了 WordcountDriver 這個類, 而上傳到服務器後, 本來我想執行的 ETLDriver 類也沒有被執行, 而是執行了 pom.xml 文件中指定的 WordcountDriver 類。 而這個類中在設置輸入路徑的時候, 指向的是 D 盤的一個目錄。 所以纔出現了這個報錯。

二、 解決方式

2.1 解決方式一

在 pom.xml 中不指定具體類, Maven 直接編譯所有的, 然後去服務器上執行的時候, 可以指定任何一個存在的類;

此時的執行語句是:

hadoop jar /opt/module/jars/mr-1.0-SNAPSHOT-jar-with-dependencies.jar com.atguigu.hive.project.gulivideo.ETLDriver /video/2008/0222 /gulivideo

即需要指定執行的類名;

2.2 解決方式二

在 pom.xml 中指定這個 ETLDriver 的類名, 但是在服務器上執行的時候, 就不要指定具體類名了, 因爲 jar 包中只允許調用 pom.xml 中指定的類了

此時的執行語句是:

hadoop jar /opt/module/jars/mr-1.0-SNAPSHOT-jar-with-dependencies.jar  /video/2008/0222 /gulivideo

即不需要再指定要執行的類的全限定名; 如果非要指定, 那麼程序會認爲指定的類名是第一個參數, 原本想要設置的輸入路徑是第二個參數(輸出路徑), 就會報錯: 輸出路徑已存在;

三、 總結

一旦執行 MapReduce 程序報了這種錯誤, 就要檢查代碼中是否設置了 D 盤的路徑, 結合報錯信息看, 是輸入路徑設置的, 就檢查輸入路徑是否設置就可以快速定位並解決掉這個異常;

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