我目前正在使用Maven进行依赖项管理。

在这种情况下,我编写了一个方法,该方法将map-reduce作业提交给hadoop,然后为该方法编写了一个junit测试。

当我运行mvn package时,它已成功编译(所有依赖项均正确),这是单元测试失败。

在作业跟踪器上,我可以看到ClassNotFoundException指示未在节点上找到我的 map ,合并和缩小类。

我不想使用conf.setJar手动为此jar文件设置路径。

有什么办法可以做到这一点自动工作?

最佳答案

您需要一种机制,以使您的用户代码(映射器,合并器,缩减器类等)可用于TaskTrackers。通常可以通过将类 bundle 到jar文件中,然后使用setJar / setJarByClass方法来处理。然后,hadoop将在后台将这个jar上传到HDFS的tmp作业目录中,并将tmp HDFS作业jar添加到分布式缓存中。

我的建议是使您的单元测试成为集成测试-在Maven生命周期的这一阶段发生在打包之后,您将拥有一个jar,然后可以通过它调用setJar并知道您将构建一个jar(猜测这里您不希望在普通测试阶段调用setJar,因为还没有构建jar。

最后,如果要在不运行实际集群的情况下测试mapper / reducer代码,则应查看MRUnit或以hadoop本地模式运行作业-两者都不需要您构建jar。

作为参考,这是一个在本地模式下运行的最小JUnit片段,该片段可在我的Ubuntu桌面上运行(如果您的桌面是Windows,则需要安装cygwin或unxutils)。这不是单元测试,因为它没有声明输出:

@Test
public void testLocalRun() throws IOException, InterruptedException, ClassNotFoundException {
    Job job = new Job();
    job.setInputFormatClass(TextInputFormat.class);
    FileInputFormat.setInputPaths(job,
            "src/test/java/csw/hadoop/sandbox/LocalHadoopTest.java");
    job.setOutputFormatClass(TextOutputFormat.class);
    TextOutputFormat.setOutputPath(job, new Path(
            "target/hadoop-local-output"));

    job.setNumReduceTasks(0);

    job.waitForCompletion(true);
}

10-06 14:45