2012-05-28 3 views
1

Book Hadoop In Action에 명시된대로 하나의 유스 케이스를 구현하려하지만 코드를 컴파일하지 않을 것입니다. 나는 자바를 처음 사용하기 때문에 오류의 정확한 원인을 이해할 수 없다.Hadoop의 DataJoins MapReduce

흥미로운 것은 동일한 클래스와 메서드를 사용하는 다른 코딩 조각이 성공적으로 컴파일된다는 것입니다.

[email protected]:~/hadoop-0.20.2/playground/src$ javac -classpath /home/hadoop/hadoop-0.20.2/hadoop-0.20.2-core.jar:/home/hadoop/hadoop-0.20.2/lib/commons-cli-1.2.jar:/home/hadoop/hadoop-0.20.2/contrib/datajoin/hadoop-0.20.2-datajoin.jar -d ../classes DataJoin2.java 
DataJoin2.java:49: cannot find symbol 
symbol : constructor TaggedWritable(org.apache.hadoop.io.Text) 
location: class DataJoin2.TaggedWritable 
      TaggedWritable retv = new TaggedWritable((Text) value); 
           ^
DataJoin2.java:69: cannot find symbol 
symbol : constructor TaggedWritable(org.apache.hadoop.io.Text) 
location: class DataJoin2.TaggedWritable 
      TaggedWritable retv = new TaggedWritable(new Text(joinedStr)); 
           ^
DataJoin2.java:113: setMapperClass(java.lang.Class<? extends org.apache.hadoop.mapreduce.Mapper>) in org.apache.hadoop.mapreduce.Job cannot be applied to (java.lang.Class<DataJoin2.MapClass>) 
     job.setMapperClass(MapClass.class); 
     ^
DataJoin2.java:114: setReducerClass(java.lang.Class<? extends org.apache.hadoop.mapreduce.Reducer>) in org.apache.hadoop.mapreduce.Job cannot be applied to (java.lang.Class<DataJoin2.Reduce>) 
     job.setReducerClass(Reduce.class); 
     ^
4 errors 

---------------- 코드 ----------------------

import java.io.DataInput; 
import java.io.DataOutput; 
import java.io.IOException; 


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.lib.input.FileInputFormat; 
import org.apache.hadoop.mapred.KeyValueTextInputFormat; 
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; 
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; 
import org.apache.hadoop.util.GenericOptionsParser; 

// DataJoin Classes 
import org.apache.hadoop.contrib.utils.join.DataJoinMapperBase; 
import org.apache.hadoop.contrib.utils.join.TaggedMapOutput; 
import org.apache.hadoop.contrib.utils.join.DataJoinReducerBase; 

import org.apache.hadoop.io.Writable; 
import org.apache.hadoop.io.WritableComparable; 


public class DataJoin2 
{ 
    public static class MapClass extends DataJoinMapperBase 
    { 
     protected Text generateInputTag(String inputFile) 
     { 
      String datasource = inputFile.split("-")[0]; 
      return new Text(datasource);    
     } 

     protected Text generateGroupKey(TaggedMapOutput aRecord) 
     { 
      String line = ((Text) aRecord.getData()).toString(); 
      String[] tokens = line.split(","); 
      String groupKey = tokens[0]; 
      return new Text(groupKey); 
     } 

     protected TaggedMapOutput generateTaggedMapOutput(Object value) 
     { 
      TaggedWritable retv = new TaggedWritable((Text) value); 
      retv.setTag(this.inputTag); 
      return retv; 
     } 
    } // End of class MapClass 

    public static class Reduce extends DataJoinReducerBase 
    { 
     protected TaggedMapOutput combine(Object[] tags, Object[] values) 
     { 
      if (tags.length < 2) return null; 
      String joinedStr = ""; 
      for (int i=0;i<values.length;i++) 
      { 
       if (i>0) joinedStr += ","; 
       TaggedWritable tw = (TaggedWritable) values[i]; 
       String line = ((Text) tw.getData()).toString(); 
       String[] tokens = line.split(",",2); 
       joinedStr += tokens[1]; 
      } 
      TaggedWritable retv = new TaggedWritable(new Text(joinedStr)); 
      retv.setTag((Text) tags[0]); 
      return retv; 
     } 
    } // End of class Reduce 

    public static class TaggedWritable extends TaggedMapOutput 
    { 
     private Writable data; 

     public TaggedWritable() 
     { 
      this.tag = new Text(""); 
      this.data = data; 
     } 

     public Writable getData() 
     { 
      return data; 
     } 

     public void write(DataOutput out) throws IOException 
     { 
      this.tag.write(out); 
      this.data.write(out); 
     } 

     public void readFields(DataInput in) throws IOException 
     { 
      this.tag.readFields(in); 
      this.data.readFields(in); 
     }  
    } // End of class TaggedWritable 

    public static void main(String[] args) throws Exception 
    { 
     Configuration conf = new Configuration(); 
     String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs(); 
     if (otherArgs.length != 2) { 
      System.err.println("Usage: DataJoin2 <in> <out>"); 
      System.exit(2); 
     } 
     Job job = new Job(conf, "DataJoin"); 
     job.setJarByClass(DataJoin2.class);  
     job.setMapperClass(MapClass.class); 
     job.setReducerClass(Reduce.class); 
     job.setInputFormatClass(TextInputFormat.class); 

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

     FileInputFormat.addInputPath(job, new Path(otherArgs[0])); 
     FileOutputFormat.setOutputPath(job, new Path(otherArgs[1])); 
     System.exit(job.waitForCompletion(true) ? 0 : 1);    
    } 
} 

답변

1

오류 메시지에 대해 모호하지 않습니다. Text 인수를 취하는 TaggedWritable에 대한 생성자를 제공하지 않았다는 것을 알려줍니다. 방금 게시 한 코드에는 인수가없는 생성자 만 표시됩니다. 당신의 처음 두 오류 메시지에 대한

+0

가리키는 주셔서 감사합니다 ....오라클 백그라운드에서 Java로 손을 잡으려고 할 때 일어나는 일입니다. – Sandeep

1

컴파일러 오류는 유형 Text의 인수를 받아 TaggedWritable에 대한 생성자가없는 것을 말하고 명확하게있습니다. 당신이 그것을 쓴대로,이 라인

을 사실

public TaggedWritable(Writable data) { 
    this.tag = new Text(""); 
    this.data = data; 
} 

: 당신이 TaggedWritable이 태그를 추가하는 Writable의 래퍼 역할을하고있다, 그래서 함께 생성자를 추가하는 것이 좋습니다 수 있다는 것을 나에게 나타납니다

this.data = data; 

data을 재 할당하기 때문에 data이라는 생성자 인수가 있어야합니다. 왜 내가 Text 대신에 Writable이되어야한다고 생각하는지 위의 이유를 참조하십시오. TextWritable을 구현하므로이 으로되어 처음 두 가지 오류 메시지가 해결됩니다.

그러나 이 필요하며,은 기본 생성자가없는 생성자입니다. 이는 Hadoop이 리플렉션을 사용하여 인스턴스 Writable 값을 맵 축소 단계 사이에서 네트워크를 통해 직렬화 할 때 인스턴스화하기 때문입니다. 난 당신이 기본적 여기를 인수 없음의 생성자를 엉망의 작은 비트를 줄 생각

public TaggedWritable() { 
    this.tag = new Text(""); 
} 

당신이 TaggedWritable.data의 유효한 인스턴스에 할당하지 않는 경우 때문에 엉망으로 이것을 볼 수있는 이유는 무엇 당신의 포장 된 Writable 값은 this.data.readFields(in)TaggedWritable.readFields(DataInput)에서 호출 될 때 NullPointerException이됩니다. 일반 래퍼이므로 TaggedWritable을 제네릭 형식으로 설정 한 다음 리플렉션을 사용하여 기본 no-arg 생성자에서 TaggedWritable.data에 할당해야합니다. 당신의 마지막 두 컴파일러 오류에 대한

, 난 당신이 된 API를 클래스를 사용하여 할 필요가 있습니다 hadoop-datajoin을 사용합니다. 따라서, 이러한

org.apache.hadoop.mapreduce.Job; 
org.apache.hadoop.mapreduce.Mapper; 
org.apache.hadoop.mapreduce.Reducer; 
org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 
org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; 
org.apache.hadoop.mapreduce.lib.input.TextInputFormat; 

모두는 그들의 오래된 API 등가물로 교체해야합니다. 따라서 org.apache.hadoop.mapreduce.Job 대신 org.apache.hadoop.mapred.JobConf 등이 필요합니다. 마지막 두 가지 오류 메시지가 처리됩니다.