2012-08-02 9 views
22

Mein Programm gegossen werden sieht aus wieHadoop: java.lang.ClassCastException: org.apache.hadoop.io.LongWritable kann nicht auf org.apache.hadoop.io.Text

public class TopKRecord extends Configured implements Tool { 

    public static class MapClass extends Mapper<Text, Text, Text, Text> { 

     public void map(Text key, Text value, Context context) throws IOException, InterruptedException { 
      // your map code goes here 
      String[] fields = value.toString().split(","); 
      String year = fields[1]; 
      String claims = fields[8]; 

      if (claims.length() > 0 && (!claims.startsWith("\""))) { 
       context.write(new Text(year.toString()), new Text(claims.toString())); 
      } 
     } 
    } 
    public int run(String args[]) throws Exception { 
     Job job = new Job(); 
     job.setJarByClass(TopKRecord.class); 

     job.setMapperClass(MapClass.class); 

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

     job.setJobName("TopKRecord"); 
     job.setMapOutputValueClass(Text.class); 
     job.setNumReduceTasks(0); 
     boolean success = job.waitForCompletion(true); 
     return success ? 0 : 1; 
    } 

    public static void main(String args[]) throws Exception { 
     int ret = ToolRunner.run(new TopKRecord(), args); 
     System.exit(ret); 
    } 
} 

Die Daten wie

sieht
"PATENT","GYEAR","GDATE","APPYEAR","COUNTRY","POSTATE","ASSIGNEE","ASSCODE","CLAIMS","NCLASS","CAT","SUBCAT","CMADE","CRECEIVE","RATIOCIT","GENERAL","ORIGINAL","FWDAPLAG","BCKGTLAG","SELFCTUB","SELFCTLB","SECDUPBD","SECDLWBD" 
3070801,1963,1096,,"BE","",,1,,269,6,69,,1,,0,,,,,,, 
3070802,1963,1096,,"US","TX",,1,,2,6,63,,0,,,,,,,,, 
3070803,1963,1096,,"US","IL",,1,,2,6,63,,9,,0.3704,,,,,,, 
3070804,1963,1096,,"US","OH",,1,,2,6,63,,3,,0.6667,,,,,,, 

auf dieses Programm läuft ich folgende auf der Konsole sehe

12/08/02 12:43:34 INFO mapred.JobClient: Task Id : attempt_201208021025_0007_m_000000_0, Status : FAILED 
java.lang.ClassCastException: org.apache.hadoop.io.LongWritable cannot be cast to org.apache.hadoop.io.Text 
    at com.hadoop.programs.TopKRecord$MapClass.map(TopKRecord.java:26) 
    at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:144) 
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764) 
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:370) 
    at org.apache.hadoop.mapred.Child$4.run(Child.java:255) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at javax.security.auth.Subject.doAs(Subject.java:396) 
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121) 
    at org.apache.hadoop.mapred.Child.main(Child.java:249) 

ich glaube, dass die Klassentypen korrekt abgebildet werden, Class Mapper,

Bitte lassen Sie mich wissen, was mache ich hier falsch?

Antwort

39

Wenn Sie eine Datei mit einem M/R-Programm lesen, sollte der Eingabetaste Ihres Mappers der Index der Zeile in der Datei sein, während der Eingabewert die vollständige Zeile sein wird.

Also hier, was passiert ist, dass Sie versuchen, den Zeilenindex als Text Objekt haben, was falsch ist, und Sie brauchen stattdessen eine LongWritable, so dass Hadoop nicht über Typ beschweren.

Versuchen Sie stattdessen:

public class TopKRecord extends Configured implements Tool { 

    public static class MapClass extends Mapper<LongWritable, Text, Text, Text> { 

     public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { 
      // your map code goes here 
      String[] fields = value.toString().split(","); 
      String year = fields[1]; 
      String claims = fields[8]; 

      if (claims.length() > 0 && (!claims.startsWith("\""))) { 
       context.write(new Text(year.toString()), new Text(claims.toString())); 
      } 
     } 
    } 

    ... 
} 

auch eine Sache in Ihrem Code, den Sie zu überdenken möchten, erstellen Sie 2 Text Objekte für jeden Datensatz Sie verarbeiten. Sie sollten diese 2 Objekte nur am Anfang erstellen und dann in Ihrem Mapper einfach ihre Werte mit der Methode set setzen. Dies spart Ihnen eine Menge Zeit, wenn Sie eine anständige Datenmenge verarbeiten.

8

müssen Sie Eingabeformat Klasse

job.setInputFormatClass(KeyValueTextInputFormat.class); 
job.setOutputFormatClass(TextOutputFormat.class); 
+1

guten Punkt setzen! Das war der Fehler in meinem Fall, gelöst durch Setzen der InputFormatClass auf 'SequenceFileInputFormat.class'. Dies funktionierte, wenn die Eingabe dieses Jobs die Ausgabe eines vorherigen Jobs war – vefthym

Verwandte Themen