java.io.IOException: No FileSystem for scheme: hdfs

java.io.IOException: No FileSystem for scheme: hdfs

  1. 问题描述
  • 程序本地能正常运行
  • 打包(Maven-assembly-plugin打包插件)到服务器上面不能运行,报出如下错误:
log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" java.io.IOException: No FileSystem for scheme: hdfs
     at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2421)
     at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2428)
     at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:88)
     at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2467)
     at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2449)
     at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:367)
     at org.apache.hadoop.fs.FileSystem$1.run(FileSystem.java:156)
     at org.apache.hadoop.fs.FileSystem$1.run(FileSystem.java:153)
     at java.security.AccessController.doPrivileged(Native Method)
     at javax.security.auth.Subject.doAs(Subject.java:422)
     at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)
     at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:153)
     at com.cetc.di.HDFSFileSystem.<init>(HDFSFileSystem.java:41)
     at callhdfs.Main.main(Main.java:11)

 

2. 原因分析

  • 原因-包覆盖:hadoop filesystem类在两个地方都有实现,分别是:hadoop-hdfs-2.7.1.jar和hadoop-common-2.7.1.jar,在这两个包的META-INF中的services目录下,都有如下的内容:

image

image

可以看到,这两个包的services目录下都有,org.apache.hadoop.fs.FileSystem这个文件。使用Maven-assembly-plugin的时候,会将所有依赖的包unpack,然后在pack,这样就会出现,同样的文件被覆盖的情况,我们看下打好的包中保留的是啥:

image

可以看到,maven-assembly-plugin(fatjar也是一样的),最后是将hadoop-common.jar中的services内容打进了最终的jar包中,而hadoop-hdfs.jar包中,services的内容被覆盖了。

 

  • HDFS底层使用的Java的ServiceLoader来做的,也就是说只有上面的service文件中声明的几种FileSystem的类,后续才会提供对应实现,而我们真正需要的是org.apache.hadoop.hdfs.DistributedFileSystem,上面并没有声明,自然也就不会提供,因此我们要么手动设置,要么使用hadoop的环境来执行jar包

 

3. 解决方案

  • 第一种:在设置hadoop的配置的时候,显示设置这个类:"org.apache.hadoop.hdfs.DistributedFileSystem",如下:
Configuration conf = new Configuration();
conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
  • 第二种:使用hadoop命令来运行jar包(此种方式更好)
hadoop jar xxx.jar
或者
yarn jar xxx.jar

 

4. 扩展:

  • ServiceLoader相关内容

jar包中META-INF中的services文件下的内容,牵涉到ServiceLoader的概念:

image

详细的介绍,看java官方文档:http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html

查看这篇文章,可以知道servicelocator具体是如何运作的http://www.concretepage.com/java/serviceloader-java-example

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值