title: Output a list from a Hadoop Map Reduce job using custom writable
body: <p>I'm trying to create a simple map reduce job by changing the wordcount example given by hadoop.</p>
  
  <p>I'm trying to out put a list instead of a count of the words. The wordcount example gives the following ouput </p>
  
  <pre><code>hello 2
  world 2
  </code></pre>
  
  <p>I'm trying to get it to output as a list, which will form the basis of future work</p>
  
  <pre><code>hello 1 1
  world 1 1
  </code></pre>
  
  <p>I think I'm on the right track but I'm having trouble writing the list. Instead of the above, I'm getting</p>
  
  <pre><code>Hello   foo.MyArrayWritable@61250ff2
  World   foo.MyArrayWritable@483a0ab1
  </code></pre>
  
  <p>Here's my MyArrayWritable. I put a sys out in the <code>write(DataOuptut arg0)</code> but it never output anything so I think that method might not be called and I don't know why.</p>
  
  <pre><code>class MyArrayWritable extends ArrayWritable{
  
  public MyArrayWritable(Class&lt;? extends Writable&gt; valueClass, Writable[] values) {
      super(valueClass, values);
  }
  public MyArrayWritable(Class&lt;? extends Writable&gt; valueClass) {
      super(valueClass);
  }
  
  @Override
  public IntWritable[] get() {
      return (IntWritable[]) super.get();
  }
  
  @Override
  public void write(DataOutput arg0) throws IOException {
      for(IntWritable i : get()){
          i.write(arg0);
      }
  }
  }
  </code></pre>
  
  <p><strong>EDIT - adding more source code</strong></p>
  
  <pre><code>public class WordCount {
  
  public static class Map extends Mapper&lt;LongWritable, Text, Text, IntWritable&gt; {
      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&lt;Text, IntWritable, Text, MyArrayWritable&gt; {
  
      public void reduce(Text key, Iterable&lt;IntWritable&gt; values, Context context) throws IOException, InterruptedException {
          ArrayList&lt;IntWritable&gt; list = new ArrayList&lt;IntWritable&gt;();    
          for (IntWritable val : values) {
              list.add(val);
          }
          context.write(key, new MyArrayWritable(IntWritable.class, list.toArray(new IntWritable[list.size()])));
      }
  }
  
  public static void main(String[] args) throws Exception {
      if(args == null || args.length == 0)
          args = new String[]{"./wordcount/input","./wordcount/output"};
      Path p = new Path(args[1]);
      FileSystem fs = FileSystem.get(new Configuration());
      fs.exists(p);
      fs.delete(p, true);
  
      Configuration conf = new Configuration();
  
      Job job = new Job(conf, "wordcount");
      job.setOutputKeyClass(Text.class);
      job.setOutputValueClass(IntWritable.class);
      job.setMapperClass(Map.class);
      job.setReducerClass(Reduce.class);
      job.setJarByClass(WordCount.class);
      job.setInputFormatClass(TextInputFormat.class);
      FileInputFormat.addInputPath(job, new Path(args[0]));
      FileOutputFormat.setOutputPath(job, new Path(args[1]));
  
      job.waitForCompletion(true);
  }
  </code></pre>
  
  <p>}</p>