解决Exception: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z 等一系列问题

本文详细记录了在Windows环境下使用Eclipse调试Hadoop2代码过程中遇到的一系列问题及其解决方案,包括配置插件、解决NullPointerException异常、权限问题等。
  

一.简介

   Windows下的 Eclipse上调试Hadoop2代码,所以我们在windows下的Eclipse配置hadoop-eclipse-plugin-2.6.0.jar插件,并在运行Hadoop代码时出现了一系列的问题,搞了好几天终于能运行起代码。接下来我们来看看问题并怎么解决,提供给跟我同样遇到的问题作为参考。

  Hadoop2的WordCount.java统计代码如下:

     

import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCount {

  public static class TokenizerMapper
       extends Mapper<Object, Text, Text, IntWritable>{

    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException {
      StringTokenizer itr = new StringTokenizer(value.toString());
      while (itr.hasMoreTokens()) {
        word.set(itr.nextToken());
        context.write(word, one);
      }
    }
  }

  public static class IntSumReducer
       extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable result = new IntWritable();

    public void reduce(Text key, Iterable<IntWritable> values,
                       Context context
                       ) throws IOException, InterruptedException {
      int sum = 0;
      for (IntWritable val : values) {
        sum += val.get();
      }
      result.set(sum);
      context.write(key, result);
    }
  }

  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    Job job = Job.getInstance(conf, "word count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    FileInputFormat.addInputPath(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}


问题一.An internal error occurred during: "Map/Reducelocation status updater".java.lang.NullPointerException

   我们hadoop-eclipse-plugin-2.6.0.jar放到Eclipse的plugins目录下,我们的Eclipse目录是F:\tool\eclipse-jee-juno-SR2\eclipse-jee-juno-SR2\plugins,重启一下Eclipse,然后,打开Window-->Preferens,可以看到Hadoop Map/Reduc选项,然后点击出现了An internal error occurredduring: "Map/Reduce location status updater".java.lang.NullPointerException,如图所示:

   

  解决:

   我们发现刚配置部署的Hadoop2还没创建输入和输出目录,先在hdfs上建个文件夹 。

   #bin/hdfs dfs -mkdir –p /user/root/input

   #bin/hdfs dfs -mkdir -p  /user/root/output

 我们在Eclipse的DFS Locations目录下看到我们这两个目录,如图所示:

  

问题二.Exception in thread "main" java.lang.NullPointerException atjava.lang.ProcessBuilder.start(Unknown Source)
  

运行Hadoop2的WordCount.java代码时出现了这样错误,

     

  log4j:WARNPlease initialize the log4j system properly.
log4j:WARN Seehttp://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" java.lang.NullPointerException
       atjava.lang.ProcessBuilder.start(Unknown Source)
       atorg.apache.hadoop.util.Shell.runCommand(Shell.java:482)
       atorg.apache.hadoop.util.Shell.run(Shell.java:455)
       atorg.apache.hadoop.util.Shell$ShellCommandExecutor.execute(Shell.java:715)
       atorg.apache.hadoop.util.Shell.execCommand(Shell.java:808)
       atorg.apache.hadoop.util.Shell.execCommand(Shell.java:791)
       at

分析:

  下载Hadoop2以上版本时,在Hadoop2的bin目录下没有winutils.exe

解决:

  1.下载https://codeload.github.com/srccodes/hadoop-common-2.2.0-bin/zip/master下载hadoop-common-2.2.0-bin-master.zip,然后解压后,把hadoop-common-2.2.0-bin-master下的bin全部复制放到我们下载的Hadoop2的binHadoop2/bin目录下。如图所示:

     

  2.Eclipse-》window-》Preferences 下的Hadoop Map/Peduce 把下载放在我们的磁盘的Hadoop目录引进来,如图所示:

    

 

  3.Hadoop2配置变量环境HADOOP_HOME 和path,如图所示:

 

 问题三.Exception in thread "main"java.lang.UnsatisfiedLinkError:org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z

  当我们解决了问题三时,在运行WordCount.java代码时,出现这样的问题

    

log4j:WARN No appenders could be found forlogger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4jsystem properly.
log4j:WARN Seehttp://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main"java.lang.UnsatisfiedLinkError:org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
       atorg.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Native Method)
       atorg.apache.hadoop.io.nativeio.NativeIO$Windows.access(NativeIO.java:557)
       atorg.apache.hadoop.fs.FileUtil.canRead(FileUtil.java:977)
       atorg.apache.hadoop.util.DiskChecker.checkAccessByFileMethods(DiskChecker.java:187)
       atorg.apache.hadoop.util.DiskChecker.checkDirAccess(DiskChecker.java:174)
       atorg.apache.hadoop.util.DiskChecker.checkDir(DiskChecker.java:108)
       atorg.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.confChanged(LocalDirAllocator.java:285)
       atorg.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:344)
       atorg.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:150)
       atorg.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:131)
       atorg.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:115)
       atorg.apache.hadoop.mapred.LocalDistributedCacheManager.setup(LocalDistributedCacheManager.java:131)

 分析:

    C:\Windows\System32下缺少hadoop.dll,把这个文件拷贝到C:\Windows\System32下面即可。

 解决:

    hadoop-common-2.2.0-bin-master下的bin的hadoop.dll放到C:\Windows\System32下,然后重启电脑,也许还没那么简单,还是出现这样的问题。

 

  我们在继续分析:

    我们在出现错误的的atorg.apache.hadoop.io.nativeio.NativeIO$Windows.access(NativeIO.java:557)我们来看这个类NativeIO的557行,如图所示:

       

 

   Windows的唯一方法用于检查当前进程的请求,在给定的路径的访问权限,所以我们先给以能进行访问,我们自己先修改源代码,return true 时允许访问。我们下载对应hadoop源代码,hadoop-2.6.0-src.tar.gz解压,hadoop-2.6.0-src\hadoop-common-project\hadoop-common\src\main\java\org\apache\hadoop\io\nativeio下NativeIO.java 复制到对应的Eclipse的project,然后修改557行为return true如图所示:

  

   

  问题四:org.apache.hadoop.security.AccessControlException: Permissiondenied: user=zhengcy, access=WRITE,inode="/user/root/output":root:supergroup:drwxr-xr-x

  我们在执行运行WordCount.java代码时,出现这样的问题

    

2014-12-18 16:03:24,092  WARN (org.apache.hadoop.mapred.LocalJobRunner:560) - job_local374172562_0001
org.apache.hadoop.security.AccessControlException: Permission denied: user=zhengcy, access=WRITE, inode="/user/root/output":root:supergroup:drwxr-xr-x
	at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkFsPermission(FSPermissionChecker.java:271)
	at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:257)
	at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:238)
	at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:179)
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkPermission(FSNamesystem.java:6512)
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkPermission(FSNamesystem.java:6494)
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkAncestorAccess(FSNamesystem.java:6446)
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.mkdirsInternal(FSNamesystem.java:4248)
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.mkdirsInt(FSNamesystem.java:4218)
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.mkdirs(FSNamesystem.java:4191)
	at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.mkdirs(NameNodeRpcServer.java:813)
   

 分析:

  我们没权限访问output目录。

解决:

    我们 在设置hdfs配置的目录是在hdfs-site.xml配置hdfs文件存放的地方,我在hadoop伪分布式部署那边有介绍过,我们在这边在复习一下,如图所示:

我们在这个etc/hadoop下的hdfs-site.xml添加

  <property> 

     <name>dfs.permissions</name> 
     <value>false</value> 
  </property>

设置没有权限,不过我们在正式的 服务器上不能这样设置。

  问题五:File/usr/root/input/file01._COPYING_ could only be replicated to 0 nodes instead ofminRepLication (=1) There are 0 datanode(s) running and no node(s) are excludedin this operation

     如图所示:

      

  分析:  

  我们在第一次执行#hadoop namenode –format 完然后在执行#sbin/start-all.sh 

在执行#jps,能看到Datanode,在执行#hadoop namenode –format然后执行#jps这时看不到Datanode ,如图所示:

      

   然后我们想把文本放到输入目录执行bin/hdfs dfs -put/usr/local/hadoop/hadoop-2.6.0/test/* /user/root/input  把/test/*文件上传到hdfs的/user/root/input中,出现这样的问题,

 解决:

  是我们执行太多次了hadoopnamenode –format,在创建了多个,我们对应的hdfs目录删除hdfs-site.xml配置的保存datanode和namenode目录。







<think>根据用户提供的引用和查询的错误信息,用户遇到的错误是:`Exception in thread "main" java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$POSIX.stat(Ljava/lang/String;)Lorg/apache/hadoop/io/nativeio/NativeIO$POSIX$Stat;` 这个错误与引用中提到的`NativeIO$Windows.access0`错误类似,都是与Hadoop的本地I/O操作相关,但具体的错误位置和方法不同。用户现在需要解决的是`NativeIO$POSIX.stat`相关的链接错误。 ### 问题分析 1. **错误类型**:`UnsatisfiedLinkError` 通常表示Java虚拟机(JVM)无法找到对应的本地方法(Native Method)实现。这里的本地方法指的是用C/C++编写并编译成动态链接库(如.dll或.so)的方法。 2. **错误位置**:`org.apache.hadoop.io.nativeio.NativeIO$POSIX.stat`,这表明Hadoop试图调用一个本地方法`stat`(用于获取文件状态),但在运行时找不到对应的本地库。 ### 可能的原因 1. **Hadoop本地库不匹配**:Hadoop的本地库(在Windows上是`.dll`文件,在Linux上是`.so`文件)可能没有正确放置或与当前操作系统不兼容。 2. **环境变量配置问题**:Hadoop需要知道本地库的位置,通常通过环境变量`HADOOP_HOME`和`PATH`来指定。 3. **Windows相关支持问题**:如果用户在Windows上运行,可能需要额外的步骤来支持Hadoop,因为Hadoop最初是为类Unix系统设计的。 ### 解决方案 根据引用[2]和[3]中提供的思路(虽然错误不完全相同,但都是`UnsatisfiedLinkError`且与`NativeIO`相关),可以尝试以下步骤: #### 1. **确保Hadoop本地库可用** - 在Hadoop的发行版中,通常有一个`bin`目录和一个`lib/native`目录,其中包含本地库文件(如`hadoop.dll`)。对于Windows系统,确保`hadoop.dll`文件存在并位于正确的位置。 - 将`hadoop.dll`文件复制到系统目录(如`C:\Windows\System32`)或者将其所在目录添加到系统的`PATH`环境变量中。 #### 2. **检查`HADOOP_HOME`环境变量** - 确保`HADOOP_HOME`环境变量已经正确设置,指向Hadoop的安装目录。 - 同时,将`%HADOOP_HOME%\bin`添加到`PATH`环境变量中,这样系统可以找到`hadoop.dll`等文件。 #### 3. **为Windows平台编译本地库** - 如果Hadoop发行版没有提供适用于Windows的本地库(例如,从Apache官网下载的二进制包通常只支持Linux),则需要自己编译。 - 可以下载Hadoop源码,并使用Windows平台的支持工具(如Microsoft Visual Studio)编译生成`hadoop.dll`。具体步骤如下: a. 安装必要的编译工具:Visual Studio、CMake、Maven等。 b.Apache Hadoop官网下载源代码。 c. 按照官方文档(如`BUILDING.txt`)中的Windows编译指南进行编译。 #### 4. **使用预编译的Windows本地库** - 为了避免自己编译的麻烦,可以寻找第三方提供的预编译的Windows本地库。例如,一些开源项目(如`hadoop-winutils`)提供了预编译的二进制文件。 - 下载后,将`bin`目录中的文件(包括`hadoop.dll`和`winutils.exe`)复制到Hadoop安装目录的`bin`目录下。 #### 5. **检查Hadoop配置文件** - 在`hadoop-env.cmd`(Windows)或`hadoop-env.sh`(Linux)中,确保`JAVA_HOME`正确设置。 - 错误信息中提到了`Error: JAVA_HOME is incorrectly set`,因此需要检查`JAVA_HOME`是否指向正确的JDK安装路径,并且路径中不包含空格(如果包含空格,需要采用短路径或使用引号)。 ### 示例步骤(Windows环境) 假设Hadoop安装在`D:\hadoop-3.3.0`,并且已经下载了预编译的Windows本地库(包含`hadoop.dll`和`winutils.exe`): 1. 将`hadoop.dll`和`winutils.exe`复制到`D:\hadoop-3.3.0\bin`目录。 2. 设置环境变量: - `HADOOP_HOME = D:\hadoop-3.3.0` - 在`PATH`中添加`%HADOOP_HOME%\bin` 3. 重启命令行窗口,确保环境变量生效。 4. 运行Hadoop程序,看是否解决。 ### 注意事项 - 如果问题仍然存在,可以尝试在Hadoop的配置文件中设置`hadoop.tmp.dir`为一个有读写权限的路径,并确保该路径没有空格。 - 确保Hadoop的版本与本地库的版本一致。 ### 相关问题 1. 如何为Hadoop编译Windows本地库? 2. 除了`hadoop.dll`,还有哪些本地库文件是必需的? 3. 如何在IDE(如IntelliJ IDEA)中配置Hadoop本地库路径? 4. Hadoop在Windows上运行还有哪些常见问题? 以上解决方案综合了用户提供的引用信息和对新错误的分析。希望这些步骤能帮助用户解决问题。 </think>### 解决 `NativeIO$POSIX.stat` 链接错误的完整方案 #### 错误原因分析 该错误是由于 Hadoop 在 Windows 环境调用本地库函数 `stat()` 时,无法找到对应的本地库实现(通常为 `hadoop.dll`)导致的。核心问题包括: 1. **本地库缺失或路径不正确**:Hadoop 的 `NativeIO$POSIX.stat` 方法依赖 `hadoop.dll` 中的本地实现 2. **平台兼容性问题**:Hadoop 原生为 Linux 设计,Windows 需额外支持文件 3. **环境配置缺陷**:`JAVA_HOME` 或 `HADOOP_HOME` 配置错误会触发连锁问题 [^3] --- ### 解决方案(Windows 环境) #### 方法一:部署 Hadoop 本地库 1. **获取 Windows 支持文件** - 下载 [winutils](https://github.com/steveloughran/winutils) 或 [hadoop.dll](https://github.com/cdarlint/winutils) 仓库 - 选择与 Hadoop 版本匹配的文件(如 hadoop-3.3.0) 2. **部署文件** ```powershell # 将以下文件复制到 HADOOP_HOME\bin 目录 hadoop.dll winutils.exe libwinutils.lib ``` 3. **设置环境变量** ```powershell # 系统环境变量 HADOOP_HOME = D:\hadoop-3.3.0 PATH += %HADOOP_HOME%\bin # 验证读写权限 winutils chmod 777 %HADOOP_HOME%\tmp ``` #### 方法二:修改 NativeIO 源码(兼容方案) 1. **创建补丁类** ```java // src/main/java/org/apache/hadoop/io/nativeio/NativeIO.java public class NativeIO { ... public static class POSIX { // 修改 stat 方法实现 public static Stat stat(String path) throws IOException { try { // Windows 文件状态检查替代逻辑 File file = new File(path); return new Stat(file.length(), file.lastModified()); } catch (SecurityException e) { throw new IOException("Permission denied: " + path); } } } } ``` 2. **编译并替换依赖** ```bash mvn package -DskipTests # 将生成的jar放入项目依赖 ``` #### 方法三:关键配置验证 1. **检查 JAVA_HOME** - 确保 `hadoop-env.cmd` 中配置无空格路径: ```cmd set JAVA_HOME=C:\PROGRA~1\Java\jdk1.8.0_301 ``` 2. **添加 VM 参数** 在运行配置中加入: ``` -Djava.library.path=%HADOOP_HOME%\bin ``` 3. **文件权限修复 ```powershell winutils.exe chmod -R 777 D:\hadoop_data ``` --- ### 验证步骤 1. 创建测试文件: ```powershell echo test > input.txt ``` 2. 执行 HDFS 操作: ```powershell hadoop fs -put input.txt /test hadoop fs -ls / ``` 3. 确认无错误输出: ``` Found 1 items -rw-r--r-- 1 user supergroup 5 2023-04-01 10:00 /test/input.txt ``` --- ### 相关问题 1. 如何解决 Windows 下 Hadoop 的 `JAVA_HOME is incorrectly set` 错误? 2. Hadoop 本地库 (`hadoop.dll`) 在不同版本间是否兼容? 3. 除了 `winutils`,还有哪些工具可以提供 Hadoop 的 Windows 支持? 4. 为什么 Hadoop 在 Linux 环境不会触发此类链接错误? > 提示:对于生产环境,建议使用 WSL2 或 Linux 虚拟机避免兼容性问题 [^2][^4]
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农_程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值