3

I have my mapper and reducers as follows. But I am getting some kind of strange exception. I can't figure out why is it throwing such kind of exception.

public static class MyMapper implements Mapper<LongWritable, Text, Text, Info> {

    @Override
    public void map(LongWritable key, Text value,
        OutputCollector<Text, Info> output, Reporter reporter)
        throws IOException {
        Text text = new Text("someText")
            //process 
        output.collect(text, infoObjeject);
    }

}

public static class MyReducer implements Reducer<Text, Info, Text, Text> {

    @Override
    public void reduce(Text key, Iterator<Info> values,
        OutputCollector<Text, Text> output, Reporter reporter)
        throws IOException {
        String value = "xyz" //derived in some way
        //process
        output.collect(key, new Text(value)); //exception occurs at this line
    }

}

System.out.println("Starting v14 ");
JobConf conf = new JobConf(RouteBuilderJob.class);
conf.setJobName("xyz");

String jarLocation =ClassUtil.findContainingJar(getClass());

System.out.println("path of jar file = " + jarLocation);

conf.setJarByClass(RouteBuilderJob.class);

conf.setMapOutputKeyClass(Text.class);
conf.setMapOutputValueClass(Info.class);

conf.setOutputKeyClass(Text.class);
conf.setOutputValueClass(Text.class);

//am i missing something here???

conf.setMapperClass(RouteBuilderJob.RouteMapper.class);
conf.setCombinerClass(RouteBuilderJob.RouteReducer.class);
conf.setReducerClass(RouteBuilderJob.RouteReducer.class);


conf.setInputFormat(TextInputFormat.class);
conf.setOutputFormat(TextOutputFormat.class);

FileInputFormat.setInputPaths(conf, new Path(args[0]));
FileOutputFormat.setOutputPath(conf, new Path(args[1]));

JobClient.runJob(conf);

I am getting an exception:

Error: java.io.IOException: wrong value class: class org.apache.hadoop.io.Text is not class com.xyz.mypackage.Info
at org.apache.hadoop.mapred.IFile$Writer.append(IFile.java:199)
at org.apache.hadoop.mapred.Task$CombineOutputCollector.collect(Task.java:1307)
at com.xyz.mypackage.job.MyJob$RouteReducer.reduce(MyJob.java:156)
at com.xyz.mypackage.job.MyJob$RouteReducer.reduce(MyJob.java:1)

Internally info object (which implements Writable) is serialized using Text

@Override
public void write(DataOutput out) throws IOException {
    Gson gson = new Gson();
    String searlizedStr = gson.toJson(this);
    Text.writeString(out, searlizedStr);
}

@Override
public void readFields(DataInput in) throws IOException {
    String s = Text.readString(in);
    Gson gson = new Gson();
    JsonReader jsonReader = new JsonReader(new StringReader(s));
    jsonReader.setLenient(true);

Info info = gson.fromJson(jsonReader, Info.class);
    //set fields using this.somefield = info.getsomefield() 
}
10
  • what is "value" here . I dont find any declaration or anything for "value" variable ? "output.collect(key, new Text(value));" in this line Commented Jan 27, 2014 at 9:35
  • @Backtrack value is a string Commented Jan 27, 2014 at 9:37
  • @Backtrack can you help me with this?i have spent lot of time debuging this Commented Jan 27, 2014 at 9:40
  • Ya sure .. Im looking into this Commented Jan 27, 2014 at 9:44
  • 3
    Problem solved after the combiner was removed. @Backtrack thanks backtrack Commented Jan 27, 2014 at 10:43

1 Answer 1

7

Technically the output types of your reduce should be the same as your input type. This must be true if you use a combiner as the output of the combiner is fed into your reducer.

Sign up to request clarification or add additional context in comments.

1 Comment

Helped me too. But any specific reason why would reducer want both types to remain same

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.