1

I am a beginner trying to learn map-reduce using java. I am trying to run the word count example using oozie coordinator. I am getting an casting error. It would be great if somebody helps me out with this error.

"Error: java.lang.ClassCastException: wordCountTest.WordCountTest cannot be cast to org.apache.hadoop.mapreduce.Mapper"

Here is my WordCountTest.java snippet:

package wordCountTest;

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.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCountTest {
 public static class TokenizerMapper
            extends Mapper<Object, Text, Text, IntWritable>{
  private final static IntWritable one = new IntWritable(1);
  private Text word = new Text();
  public void map(Object key, Text value, Context context
        ) throws IOException, InterruptedException {
   StringTokenizer itr = new StringTokenizer(value.toString());
   while (itr.hasMoreTokens()) {
    word.set(itr.nextToken());
    context.write(word, one);
   }
  }
 }
 public static class IntSumReducer
            extends Reducer<Text,IntWritable,Text,IntWritable> {
  private IntWritable result = new IntWritable();    
  public void reduce(Text key, Iterable<IntWritable> values,
                           Context context
        ) throws IOException, InterruptedException {
   int sum = 0;
   for (IntWritable val : values) {
    sum += val.get();
   }
   result.set(sum);
   context.write(key, result);
  }
 }
 public static void main(String[] args) throws Exception {
  Configuration conf = new Configuration();
  Job job = new Job(conf,"WordCount");
  job.setJarByClass(WordCountTest.class);
  job.setMapperClass(TokenizerMapper.class);
  job.setCombinerClass(IntSumReducer.class);
  job.setReducerClass(IntSumReducer.class);
  job.setOutputKeyClass(Text.class);
  job.setOutputValueClass(IntWritable.class);
  FileInputFormat.addInputPath(job, new Path(args[0]));
  FileOutputFormat.setOutputPath(job, new Path(args[1]));
  System.exit(job.waitForCompletion(true) ? 0 : 1);
 }
}

Also , my workflow.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<workflow-app xmlns="uri:oozie:workflow:0.1" name="map-reduce-wf">
 <start to="mr-node" />
 <action name="mr-node">
  <map-reduce>
   <job-tracker>${jobTracker}</job-tracker>
   <name-node>${nameNode}</name-node>
   <configuration>
    <property>
     <name>mapred.mapper.new-api</name>
     <value>true</value>
    </property>
    <property>
     <name>mapred.reducer.new-api</name>
     <value>true</value>
    </property>
    <property>
     <name>mapred.job.queue.name</name>
     <value>${queueName}</value>
    </property>
    <property>
     <name>mapreduce.map.class</name>
     <value>wordCountTest.WordCountTest.TokenizerMapper</value>
    </property>
    <property>
     <name>mapreduce.reduce.class</name>
     <value>wordCountTest.WordCountTest.IntSumReducer</value>
    </property>
    <property>
     <name>mapreduce.combine.class</name>
     <value>wordCountTestEmr.WordCountTest.IntSumReducer</value>
    </property>
    <property>
     <name>mapred.output.key.class</name>
     <value>org.apache.hadoop.io.Text</value>
    </property>
    <property>
     <name>mapred.output.value.class</name>
     <value>org.apache.hadoop.io.IntWritable</value>
    </property>
    <property>
     <name>mapred.input.dir</name>
     <value>/user/ahegde/testemr/InputData/</value>
    </property>
    <property>
     <name>mapred.output.dir</name>
     <value>/user/ahegde/testemr/OutputData</value>
    </property>
   </configuration>
  </map-reduce>
 <ok to="end" />
 <error to="fail" />
 </action>
  <kill name="fail">
   <message>Map/Reduce failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
  </kill>
  <end name="end" />
 </workflow-app>
Binary Nerd
  • 13,872
  • 4
  • 42
  • 44
Blank
  • 81
  • 11
  • check this [link](http://stackoverflow.com/questions/21722173/getting-java-lang-classcastexception-class-java-lang-string-in-running-a-simple) – Ravindra Devadiga Aug 09 '16 at 04:30
  • Why you want to make mapper and reducer classes Static? could you please remove static for map class and reduce class and also if possible please take them out and create as separate classes in the same package and give a try. – Aditya Aug 09 '16 at 04:38

1 Answers1

0

You probably need to change your Oozie config since these are inner static classes to:

<property>
    <name>mapreduce.map.class</name>
    <value>wordCountTest.WordCountTest$TokenizerMapper</value>
</property>

The change is the . to a $.

Binary Nerd
  • 13,872
  • 4
  • 42
  • 44