HDFS编程实战中出现的问题

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

系统环境:

  • ubuntu 14.04 LTS
  • Hadoop 2.7.6
  • Eclipse 3.8.1
  • javaSE-1.7

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

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

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

编写代码后运行:

问题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包以查看源码,具体添加插件可以参考下面这篇博客

插件安装完成后,常按住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包才行,这个问题我也没有找到答案,可能是视频中的某些细节我没有注意到吧,有时间再回去看看!也希望有机会看到这篇博文的朋友能提点一下。

感谢这些博主:

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