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程序版本不一致导致的。我这边就暂时不作深究了。。

     

     

  • 相关阅读:
    Saltstack module gem 详解
    Saltstack module freezer 详解
    Saltstack module firewalld 详解
    Saltstack module file 详解
    Saltstack module event 详解
    Saltstack module etcd 详解
    Saltstack module environ 详解
    Saltstack module drbd 详解
    Saltstack module dnsutil 详解
    获取主页_剥离百度
  • 原文地址:https://www.cnblogs.com/chorm590/p/10252752.html
Copyright © 2011-2022 走看看