Junior hpc
Junior hpc

Reputation: 169

Running Implementing Custom Output Format in Hadoop Tutorial

I want to run the code described in this tutorial in order to customize the output format in Hadoop. More precisely, the tutorial shows two java files:

  1. WordCount: is the word count java application (similar to the WordCount v1.0 of the MapReduce Tutorial in this link)
  2. XMLOutputFormat: java class that extends FileOutputFormat and implements the method to customize the output.

Well, what I did was to take the WordCount v1.0 of the MapReduce Tutorial (instead of using the WordCount showed in the tutorial) and add in the driver job.setOutputFormatClass(XMLOutputFormat.class); and execute the hadoop app in this way:

/usr/local/hadoop/bin/hadoop com.sun.tools.javac.Main WordCount.java && jar cf wc.jar WordCount*.class && /usr/local/hadoop/bin/hadoop jar wc.jar WordCount /home/luis/Desktop/mytest/input/ ./output_folder

note: /home/luis/Desktop/mytest/input/ and ./output_folder are the input and output folders, respectively.

Unfortunately, the terminal shows me the following error:

WordCount.java:57: error: cannot find symbol job.setOutputFormatClass(XMLOutputFormat.class); ^ symbol: class XMLOutputFormat location: class WordCount 1 error

Why? WordCount.java and XMLOutputFormat.java are stored in the same folder.

The following is my code.

WordCount code:

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 WordCount {

  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 = Job.getInstance(conf, "word count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    job.setOutputFormatClass(XMLOutputFormat.class);
    FileInputFormat.addInputPath(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);



  }
}

XMLOutputFormat code:

import java.io.DataOutputStream; 
import java.io.IOException;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.RecordWriter;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class XMLOutputFormat extends FileOutputFormat<Text, IntWritable> {

    protected static class XMLRecordWriter extends RecordWriter<Text, IntWritable> {

        private DataOutputStream out;

        public XMLRecordWriter(DataOutputStream out) throws IOException{

            this.out = out;
            out.writeBytes("<Output>\n");

        }


        private void writeStyle(String xml_tag,String tag_value) throws IOException {

            out.writeBytes("<"+xml_tag+">"+tag_value+"</"+xml_tag+">\n");

        }

        public synchronized void write(Text key, IntWritable value) throws IOException {

            out.writeBytes("<record>\n");
            this.writeStyle("key", key.toString());
            this.writeStyle("value", value.toString());
            out.writeBytes("</record>\n");

        }

        public synchronized void close(TaskAttemptContext job) throws IOException {

            try {

                out.writeBytes("</Output>\n");

            } finally {

                out.close();

            }

        }

    }

    public RecordWriter<Text, IntWritable> getRecordWriter(TaskAttemptContext job) throws IOException {

        String file_extension = ".xml";
        Path file = getDefaultWorkFile(job, file_extension);
        FileSystem fs = file.getFileSystem(job.getConfiguration());
        FSDataOutputStream fileOut = fs.create(file, false);
        return new XMLRecordWriter(fileOut);

    }

}

Upvotes: 0

Views: 856

Answers (2)

kashmoney
kashmoney

Reputation: 97

We will need to add the XMLOutputFormat.jar file to the HADOOP_CLASSPATH first for the driver code to find it. And pass it in -libjars option to be added to classpath of the map and reduce jvms.

export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/abc/xyz/XMLOutputFormat.jar

yarn jar wordcount.jar com.sample.test.Wordcount 
-libjars /path/to/XMLOutputFormat.jar 
/lab/mr/input /lab/output/output

Upvotes: 1

κροκς
κροκς

Reputation: 590

You need to either add package testpackage; at the beginning of your WordCount class

or

import testpackage.XMLOutputFormat; in your WordCount class.

Because they are in the same directory, it doesn't imply they are in the same package.

Upvotes: 1

Related Questions