HDFS编程实战中出现的问题

    xiaoxiao2023-10-01  151

    问题来源:慕课网——厦门大学林子雨老师主讲《大数据技术原理与应用》——3.6-HDFS编程实战

    系统环境:

    ubuntu 14.04 LTSHadoop 2.7.6Eclipse 3.8.1javaSE-1.7

    补充:系统环境的搭配参考:http://dblab.xmu.edu.cn/blog/install-hadoop/

    编程前——按视频教程中的配置

    打开Eclipse创建项目HadTest(项目名自取)导入jar包hadoop-common-2.7.6.jar(jar包位于/usr/local/hadoop/share/hadoop/common/)将core-site.xml与hdfs-site.xml复制到项目HadTest下的bin文件下(*.xml文件位于/usr/local/hadoop/etc/hadoop/)编写代码

    编写代码后运行:

    问题1——Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory

    异常显示没有发现类org.apache.commons.logging.LogFactory,分析为jar包缺失,在/usr/local/hadoop/share/hadoop/common/lib/下找到jar包commons-logging-1.1.3.jar导入后,该问题解决

    上面问题解决后接着运行程序:

    问题2——Caused by: java.lang.ClassNotFoundException: com.google.common.base.Preconditions

    异常显示没有发现类com.google.common.base.Preconditions,分析为jar包缺失,在/usr/local/hadoop/share/hadoop/common/lib/下找到jar包guava-11.0.2.jar导入后,该问题解决

    继续运行程序:

    问题3——Caused by: java.lang.ClassNotFoundException: org.apache.commons.collections.map.UnmodifiableMap

    异常显示没有发现类org.apache.commons.collections.map.UnmodifiableMap,分析为jar包缺失,在/usr/local/hadoop/share/hadoop/common/lib/下找到jar包commons-collections-3.2.2.jarr导入后,该问题解决

    问题4——Caused by: java.lang.ClassNotFoundException: org.apache.commons.configuration.Configuration

    异常显示没有发现类org.apache.commons.configuration.Configuration,分析为jar包缺失,在/usr/local/hadoop/share/hadoop/common/lib/下找到jar包commons-configuration-1.6.jar导入后,该问题解决

    问题5——Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang.StringUtils

    解决:导入/usr/local/hadoop/share/hadoop/common/lib/commons-lang-2.6.jar,该问题解决

    问题6——Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.util.PlatformName

    解决:导入/usr/local/hadoop/share/hadoop/common/lib/hadoop-auth-2.7.6.jar,该问题解决

    问题7——Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory

    解决:导入/usr/local/hadoop/share/hadoop/common/lib/slf4j-api-1.7.10.jar,该问题解决


    问题8——java.io.IOException: No FileSystem for scheme: hdfs

    问题具体描述:

    可以看出异常出现在第13行代码:FileSystem fs=FileSystem.get(configuration)。与FileSystem类中的get方法有关,该类位于jar包hadoop-common-2.7.6.jar中。在linux操作系统中用归档管理器打开该jar包,可以看到对应的.class文件

    用Eclipse反编译该jar包以查看源码,具体添加插件可以参考下面这篇博客

    eclipse添加反编译插件实现查看jar源码我在这里出现的问题是,在我的Eclipse->help中没有Eclipse Marketplace选项,解决办法是参考另一篇博客eclipse 的help没有Eclipse Marketplace真心吐嘈这个下载速度,慢得ya匹

    插件安装完成后,常按住Ctrl键,然后点击 类 || 接口 || 方法(FileSystem.get()) 名,即可进入源码

    继续分析异常为java.io.IOException: No FileSystem for scheme: hdfs。以IOException为目标一个方法一个方法点进去看

    最后是在这里发现了熟悉的东西:No FileSystem for scheme: hdfs

    分析:抛出No FileSystem for scheme: hdfs异常语句的原因是clazz为null,该方法的目的是反射加载类。

    第一步:loadFileSystems();

    装填HashMap容器SERVICE_FILE_SYSTEMS,该方法只执行一次

    第二步:clazz = conf.getClass("fs." + scheme + ".impl", null);

    看注释可以知道,该方法可以根据name获取对应的Class对象,该对象应该是作为了一个属性值与成映射关系,如果没有该name属性,即返回defaultValue,在上一个方法中即返回null

    第三步:clazz = (Class) SERVICE_FILE_SYSTEMS.get(scheme);

    由此可以分析出,clazz一直为空,在第二步也就是配置文件中没有找到属性为fs.hdfs.impl的配置,且在第一步装填容器中也没有存在key为hdfs的映射关系

    于是有了一个初步的解决方案:1、找到配置文件,在里面加上fs.hdfs.impl配置;2、继续研究loadFileSystems(),找到将hdfs映射关系写入Map容器中的方法。

    之后我直接将fs.hdfs.impl复制到百度去搜索,筛选到这篇博客hadoop三个配置文件的参数含义说明

    知道了配置文件名为core-default.xml,fs.hdfs.impl映射值为org.apache.hadoop.hdfs.DistributedFileSystem

    接下来就要找到core-default.xml,然后将映射关系写进去

    因为不知道配置文件的具体路径,直接在usr/local/hadoop/下搜索core-default.xml

    发现有两个一模一样的文件,那就一个一个的试吧

    运行,发现还是老样子,貌似修改这两个配置文件没有任何毛用,想起前段时间自己做的jar可执行程序,配置文件保存位置有两种选择,一是不与程序一起打包(即放在jar包外),另一种是和程序一起打包(即在jar包内部),所以我再次用linux中的归档管理器打开hadoop-common-2.7.6.jar

    嗯!发现了,这里有一个配置文件,盘他。

    完成后,再次运行程序!!!


    问题9——Caused by: java.lang.ClassNotFoundException: Class org.apache.hadoop.hdfs.DistributedFileSystem not found

    解决:导入/usr/local/hadoop/share/hadoop/common/lib/jackson-mapper-asl-1.9.13.jar /usr/local/hadoop/share/hadoop/common/lib/htrace-core-3.1.0-incubating.jar /usr/local/hadoop/share/hadoop/common/lib/commons-cli-1.2.jar /usr/local/hadoop/share/hadoop/common/lib/protobuf-java-2.5.0.jar /usr/local/hadoop/share/hadoop/common/lib/commons-io-2.4.jar /usr/local/hadoop/share/hadoop/hdfs/hadoop-hdfs-2.7.6.jar这些包

    最后的程序虽然有了输出,但还是有一个异常,我看了该类,明明在jar包中且该jar包已经导入了项目,这就不是我理解的了


    所以我最后的解决方案是:将/usr/local/hadoop/share/hadoop/common/lib/下的所有jar包,/usr/local/hadoop/share/hadoop/common/下的三个jar包,/usr/local/hadoop/share/hadoop/hdfs/下的hadoop-hdfs-2.7.6.jar一起导入到项目中,然后运行项目

    。。。。。。。。。。。。。

    总结:这是我学习大数据技术的第一个编程实践,很曲折,明明是按照视频教学里的步骤来的,结果还是各种错,虽然最后以空间(导入所有的jar包)换取了正解,但中间对异常的分析思路是自己在找bug技术上的一次突破。回去看看,其实这个实践的重点在第8个问题中,至于为什么视频教学里老师只导入一个jar包就可以正常执行程序,而我需要导入所有的jar包才行,这个问题我也没有找到答案,可能是视频中的某些细节我没有注意到吧,有时间再回去看看!也希望有机会看到这篇博文的朋友能提点一下。

    感谢这些博主:

    eclipse添加反编译插件实现查看jar源码hadoop三个配置文件的参数含义说明eclipse 的help没有Eclipse Marketplace
    最新回复(0)