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 盘的路径, 结合报错信息看, 是输入路径设置的, 就检查输入路径是否设置就可以快速定位并解决掉这个异常;

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