【问题标题】:Using FsShell.run() to get remote hdfs file throws null pointer exception使用FsShell.run()获取远程hdfs文件抛出空指针异常
【发布时间】:2016-04-16 21:29:57
【问题描述】:

我需要在 java 代码中实现一个快速简单的 hdfs get 功能,它的工作方式与命令行“hadoop fs get”非常相似,因为它支持通配符。

使用Filesystem.copyToLocalFile() 方法似乎无法提供此功能,但使用适当参数运行FsShell.run() 似乎调用了确切的命令行功能,但由于某种原因,它在执行获取时会引发空指针异常。

我的代码如下:

        Configuration conf = new Configuration();
        conf.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
        conf.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName());

        FileSystem.setDefaultUri(conf, "hdfs://192.168.61.129:8020");

        FsShell hdfsShell = new FsShell(conf);


        String src = "/user/andrei-test/test.txt";
        String dst = "D:/temp/";

        hdfsShell.run(new String[]{ "-get", src, dst });

我还注意到在做 put 时:

hdfsShell.run(new String[]{ "-put", "D:/temp/test.txt", "/user/andrei-test/test-put.txt" });

一切正常。

进入调试模式,我注意到 java.lang.ProcessBuilder.start() 方法抛出了异常:

for (String arg : cmdarray)
        if (arg == null)
            throw new NullPointerException();

当cmd数组有以下值时:

[null, chmod, 0644, D:\temp\test.txt._COPYING_]

从这里我有点难过,以前有人遇到过这个问题吗?我也找不到在 google 上使用 FsShell.run() 进行 get 的示例,我觉得这有点奇怪。

【问题讨论】:

  • 您的 cmdarray 转储有 chmod,但您在上面发布的代码在调用 hdfsShell 时有 get。你确定你做对了吗?
  • 我很确定它是正确的,再次,带有 put 的版本,正如我同时尝试过的那样,带有 rm 的工作就好了。我假设 D:\temp\test.txt._COPYING_ 是为反映操作状态或类似内容而创建的中间文件。
  • 作为一个小更新,我已经在单独的 hadoop 集群、我们在这里使用的开发集群以及我在本地运行的 hortonworks vm 上检查了这一点。我正在使用的依赖项是 hadoop-common 和 hadoop-hdfs,我也尝试过使用它们的不同版本。在所有这些情况下,我都得到了相同的结果。
  • 如果您发布堆栈跟踪可能会有所帮助
  • 对不起,是的,我想我可以从堆栈跟踪开始。 pastebin.com/K0796e9F

标签: java hadoop hdfs


【解决方案1】:

显然,以这种方式进行获取不像通过 FileSystem.copyToLocalFile() 进行获取那样独立工作

最终修复它的是创建一个环境变量 HADOOP_HOME 并确保存在 %HADOOP_HOME%\bin\winutils.exe

【讨论】:

    猜你喜欢
    • 2017-12-20
    • 1970-01-01
    • 2018-03-20
    • 2012-05-27
    • 2020-11-22
    • 2020-08-10
    • 2013-03-21
    • 1970-01-01
    相关资源
    最近更新 更多