我目前正在使用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);
}