一、报错信息
第一种:
Exception in thread "main" java.lang.RuntimeException:
Error while running command to get file permissions :
java.io.IOException: (null) entry in command string:
null ls -F G:\hadooptest\input\order.txt
第二种:
Exception in thread "main" java.lang.UnsatisfiedLinkError:
org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
第三种:
Exception in thread "main" java.io.IOException:
(null) entry in command string: null chmod 0700 F:\tmp\hadoop-
ThinPeng\mapred\staging\ThinPeng1488563454\.staging
二、错误原因
以上错误出现的原因都是 MapReduce 在 Windows 环境下,bin 目录缺少某些文件导致(如 winutils.exe、hadoop.dll 等)
三、解决方法
1、到 hadoop 官网下载压缩包后解压,然后去网上搜索别人提供的相应版本的windows所需补充文件放到 bin 目录下。
(或者自己下载源码进行编译)
(我也上传了一个适合win10的 hadoop 完整包,2.7.6版本,下载地址:hadoop-2.7.6 for win10)
2、配置环境变量:
HADOOP_HOME : E:\haoop-2.7.6
PATH 添加: %HADOOP_HOME%\bin
3、如果以上还不能解决问题,尝试把你的 input 路径写到具体文件试试?网上看到的,我没重现出这个问题。
如:·
四、问题查找分析
我一开始遇到的是第三种报错,后来发现玩了那么久,竟然是自己本地没安装 hadoop 环境,然后想起来之前可能一直是在虚拟机集群环境下运行的。虽然自己也网上搜索了一下解决方法,但是感觉有点乱,最后干脆自己通过源码跟踪,寻找问题所在。
本来想写一段具体的源码分析的,结果不知道如何下手,直接上关键代码吧,具体可以自己手动断点尝试下,还是挺简单的。
1、MapReduce 在运行过程中,需要操作 windows 文件系统,在这个过程需要去获取相关的执行命令,如下图,发现这里的 WINUTILS 为 null,后面的代码会对这个 String[] 进行检查,如果存在为 null 的成员,就会报错,这下知道错误信息中 “null chmod 0700” 是怎么来的了吧!
2、这个 WINUTILS 是怎么来的呢?直接上图了:
3、由上图的 fullExeName 可知,这里容易导致获取文件失败的就是两个地方:
(1)HADOOP_HOME_DIR 是否正确,即是否安装了 HADOOP 并配置了环境变量“HADOOP_HOME”;
(2)bin 目录下是否存在 winutils.exe。
4、对于其他两种报错,大概也都是跟第三种一样的原因,说白了都是运行环境的问题。
五、扩展
其实,如果有配置好 log4j,也不需要上面的源码分析,从打印的错误日志就能看出来具体是什么问题了。可能许多人跟我一样,只是想写个小的程序体验一下,就没去配置日志,导致没能看到详细的错误信息。
具体如何配置,其实网上搜一下就有了,还是很简单的,只是添加个配置文件而已。
最终打印出来的日志如下图,是不是很清楚?就是跟你说 bin 目录下找不到 winutils.exe~ :