【问题标题】:ClassNotFoundException when running WordCount example in Eclipse在 Eclipse 中运行 WordCount 示例时出现 ClassNotFoundException
【发布时间】:2013-11-15 02:02:58
【问题描述】:

我正在尝试运行 WordCount map/reduce 作业的示例代码。我在 Hadoop 1.2.1 上运行它。我正在从我的 Eclipse 运行它。这是我尝试运行的代码:

package mypackage;

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.LongWritable;
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.Reducer.Context;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;


public class WordCount {

    public static class Map extends
            Mapper<LongWritable, Text, Text, IntWritable> {
        private final static IntWritable one = new IntWritable(1);
        private Text word = new Text();

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

    public static class Reduce extends
            Reducer<Text, IntWritable, Text, IntWritable> {

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

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        conf.set("mapred.job.tracker", "maprfs://,y_address");
        conf.set("fs.default.name", "hdfs://my_address");

        Job job = new Job(conf, "wordcount");
        job.setJarByClass(WordCount.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        job.setMapperClass(Map.class);
    job.setReducerClass(Reduce.class);

        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);

        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        job.waitForCompletion(true);    
    }   
}

不幸的是,运行此代码最终会出现以下错误:

13/11/04 13:27:53 信息 mapred.JobClient:任务 ID: 尝试_201310311611_0005_m_000000_0,状态:失败 java.lang.RuntimeException: java.lang.ClassNotFoundException: com.rf.hadoopspikes.WordCount$Map 在 org.apache.hadoop.conf.Configuration.getClass(Configuration.java:857) 在 org.apache.hadoop.mapreduce.JobContext.getMapperClass(JobContext.java:199) 在 org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:718) 在 org.apache.hadoop.mapred.MapTask.run(MapTask.java:364) 在 org.apache.hadoop.mapred.Child$4.run(Child.java:255) 在 java.security.AccessController.doPrivileged(Native Method) 在 javax.security.auth.Subject.doAs(Subject.java:415) 在 org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1190) 在 org.apache.hadoop.mapred.Child.main(Child.java:249)

我知道找不到 WordClass,但我不知道如何进行这项工作。 有什么想法吗?

【问题讨论】:

  • 这通常是一个依赖问题,您的类路径中可能有多个版本的 jar,其中包含 com.rf.hadoopspikes.WordCount$Map 类,或者 jar 的版本与代码示例不兼容(例如,您在 main 方法开始时设置的选项可能不适用于您的版本)

标签: java eclipse hadoop mapreduce


【解决方案1】:

当直接从 Eclipse 运行时,您需要确保这些类已经被捆绑到一个 Jar 文件中(然后 hadoop 会为此复制到 HDFS)。您的错误很可能与您的 Jar 尚未构建这一事实有关,或者在运行时这些类是从输出目录而不是捆绑的 jar 运行的。

尝试将类导出到 jar 文件中,然后从该 Jar 文件运行 WordCount 类。您还可以考虑使用 Eclipse Hadoop 插件,我认为它可以处理您的所有这些问题。最后的选择是捆绑 jar,然后从命令行启动(如各种 Hadoop 教程中所述)

【讨论】:

  • 这是否意味着我必须将我的类放入一个 jar 文件中才能在 Hadoop 上运行代码?如果每次我想测试我的代码时都必须创建一个 jar 文件,这会给 map-reduce 应用程序的开发过程增加一些负担。
  • 是的,您确实需要将您的类捆绑到一个可部署的 jar 中——而 hadoop 不能仅仅猜测它需要发布哪些类。至于测试,还有其他方法可以测试您的代码 - MRUnit 和使用 LocalJobRunner 是我想到的两种方法
猜你喜欢
  • 1970-01-01
  • 2015-03-19
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
  • 2015-08-07
  • 1970-01-01
相关资源
最近更新 更多