zoukankan      html  css  js  c++  java
  • Eclipse maven hadoop -- java.io.IOException: No FileSystem for scheme: hdfs

    2019-01-10

    概述

      今天在Windows系统下新安装了Eclipse和maven的环境,想利用Maven构建一个Hadoop程序的,结果却发现程序运行时一直报 “No FileSystem for scheme: hdfs” 的异常。网友贴出的解决方案在我这都不适用。经过数小时痛苦的折磨以后才终于找到我这种情况的原因:Maven自动下载的 hadoop-hdfs-2.7.7.jar 库文件不正确!!!

    环境

    HDFS搭建在一组ubuntu server集群上,系统正常运行。 Hadoop 2.7.7

    Windows 10 下安装:

    1. Eclipse  Photon Release (4.8.0)
    2. JDK 1.8
    3. Maven 3.6.0

    Eclipse上所使用的主要源码如下:

     1     void access() {
     2         Configuration conf = new Configuration();
     3         conf.set("fs.defaultFS", "hdfs://usmaster:8020");
     4         try {
     5             FileSystem fs = FileSystem.get(conf); //运行到该行时报异常。
     6             System.out.println(fs.getHomeDirectory().toUri().toString());
     7             System.out.println("read end!");
     8         } catch (Exception e) {
     9             e.printStackTrace();
    10         }
    11     }

    异常栈信息如下:

    java.io.IOException: No FileSystem for scheme: hdfs
        at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2658)
        at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2665)
        at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:93)
        at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2701)
        at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2683)
        at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:372)
        at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:171)
        ...

    解决过程

      遇到这个问题,首先思考下异常原因:No FileSystem for scheme: hdfs 。似乎是不能识别hdfs协议!那首先来检查一下HDFS系统的运行状况。经检查,我的HDFS集群运行正常。WEB UI正常打开,也可以通过Shell命令正常地与HDFS交互。排除掉HDFS系统的原因。

      其次检查我的源代码,为了纠错将源代码缩减到最减化的地步,如上面贴出来的代码所示。根据代码来看,也可以排除掉我写的代码有错误的原因。

      然后再检查Maven的pom配置信息。我的pom.xml全文如下所示:

     1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     2   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     3   <modelVersion>4.0.0</modelVersion>
     4 
     5   <groupId>com.chorm</groupId>
     6   <artifactId>HelloWorld</artifactId>
     7   <version>0.0.1-SNAPSHOT</version>
     8   <packaging>jar</packaging>
     9 
    10   <name>HDFS</name>
    11   <url>http://maven.apache.org</url>
    12 
    13   <properties>
    14     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    15     <hadoop.version>2.7.7</hadoop.version>
    16   </properties>
    17 
    18   <dependencies>
    19     <dependency>
    20       <groupId>junit</groupId>
    21       <artifactId>junit</artifactId>
    22       <version>3.8.1</version>
    23       <scope>test</scope>
    24     </dependency>
    25     
    26     <dependency>
    27       <groupId>org.apache.hadoop</groupId>
    28       <artifactId>hadoop-client</artifactId>
    29       <version>${hadoop.version}</version>
    30     </dependency>
    31     
    32   </dependencies>
    33 </project>

      同时检查了项目的Maven Dependencies,该有的jar包都有。似乎也和Maven依赖没关系。

      那接下来再检查JRE,似乎也没发现问题。。。

      好嘛,检查一圈下来哪哪都没问题,那它怎么就是报错???

     

      现在只剩百度了。。。经过一番搜索,网上虽然也有不少报相同异常的情况,但是按照他们的方案都没能解决我的问题。还得继续靠自己来分析。。。

     

    那我就不用Maven来构建程序。我直接创建一个Java Project,看看有没有可能是我下载的Maven程序有问题。创建Java Project的过程大致如下:

    1. 新建一个Java Project
    2. 贴上上面的源代码
    3. 在HDFS集群上将 ./hadoop/share/hadoop 目录下相关的jar库拷出来,添加到Project依赖库中。
    4. run it...

     

    正常运行。。。

    这似乎真和Maven脱不了干系。

     

    那只能调试程序了。。。。

    首先定位到抛出这个异常的代码:

    at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2658)

    图1 

      由上图来看,抛异常是因为claszz变量在第2652行第2655行都没能得到对象引起的(找不到对象的变量真的是可怕)。第2652行是要从Configuration对象中读取配置信息的,就是从core-default.xml或core-site.xml中读取配置信息。这个信息我这边并没有指定,所以它肯定是返回一个NULL的。那我们在第2654行打一个断点,来调试一下看怎么回事。

    图2

      单步跳过第2655行以后看一下这个SERVICE_FILE_SYSTEMS变量。

    图3

      似乎这个对象里真的没有key值能匹配“hdfs”的对象值啊。这就有点奇怪了。那再调试一下前面自己建的那个“Java Project”,在同样位置打断点来查看这个变量值。

    图4

      神奇了。。。为什么用maven构建的程序会导致这个SERVICE_FILE_SYSTEMS变量里没有“hdfs”的对象?去看看这个SERVICE_FILE_SYSTEMS是在哪里赋值的。

    图5

      查了源码,这个SERVICE_FILE_SYSTEMS只在这一处地方有赋值操作。其值来自于ServiceLoader.load(FileSystem.class)。我不了解这个ServiceLoader.load()方法是干什么的,不过似乎和hadoop的FileSystem有关系,经查询这个FileSystem来自于hadoop-common-2.7.7.jar库。这个FileSystem类在Maven构建的程序中的依赖库中能找到,在Java Project中手动添加的依赖库中也能找到。

    图6

      再去查一下上图4中那个与“hdfs”有关的DistriubtedFileSystem的类。却发现只能在自己创建的Java Project中找到它位于hadoop-hdfs-2.7.7.jar中,在Maven构建的程序中没有!!难道是maven自动下载的hadoop-hdfs-2.7.7.jar 库有问题?打开来看一下。

    图7

      神奇有没有,maven自动下载的库中也有这个class。但是为什么似乎Eclipse就是识别不到它??

      再对比一下这两个hadoop-hdfs-2.7.7.jar的文件属性信息。

    图8

      文件大小显然不一样,这两个库有差异啊!

      那将我手动从HDFS中导出来的hadoop-hdfs-2.7.7.jar替换掉我Maven自动下载的那个hadoop-hdfs-2.7.7.jar来试试。

    图9

      运行程序。。

    图10

      问题解决!!!!

     

      不过我至今搞不懂为什么maven自动下载的那个hadoop-hdfs-2.7.7.jar库会不行。。也搞不懂这两个库之间的差异是怎么回事。

      不过我这边安装的HDFS是直接在Hadoop的官网上下载的2.7.7版本。我不知道Maven帮我下载的库是不是什么CDH版本的。也许真的是依赖库文件来源的Hadoop程序版本不一致导致的。我这边就暂时不作深究了。。

     

     

  • 相关阅读:
    20210907
    彻底解决Manjaro中的编程字体问题
    manjaro上安装腾讯会议
    应对github的新变换,更加方便应用github
    Failed to stop iptables.service: Unit iptables.service not loaded.
    centOS7给虚拟机设置固定ip地址
    centOS给虚拟机设置固定ip地址
    SpringBoot启动报错Failed to determine a suitable driver class
    Jasypt加解密
    java json字符串转JSONObject对象、转JAVA对象、转List<T>对象
  • 原文地址:https://www.cnblogs.com/chorm590/p/10252752.html
Copyright © 2011-2022 走看看