2015-04-04 11 views
5

Non ho ancora visto una soluzione al mio particolare problema. Non funziona almeno. Mi sta facendo diventare pazzo. Questa particolare combo non sembra avere molto nello spazio di google. Il mio errore si verifica come il lavoro fa nel mappatore da quello che posso dire. L'input per questo lavoro è l'output dello schema avro che è compresso con deflate anche se ho provato anche non compresso.Interfaccia trovata org.apache.hadoop.mapreduce.TaskAttemptContext

Avro: 1.7.7 Hadoop: 2.4.1

sto ottenendo questo errore e non sono sicuro perché. Ecco il mio lavoro, mappatore e riduzione. L'errore sta accadendo quando il mapper viene in

Esempio file di input Avro non compresso (StockReport.SCHEMA è definito in questo modo)

{"day": 3, "month": 2, "year": 1986, "stocks": [{"symbol": "AAME", "timestamp": 507833213000, "dividend": 10.59}]} 

lavoro

@Override 
public int run(String[] strings) throws Exception { 
    Job job = Job.getInstance(); 
    job.setJobName("GenerateGraphsJob"); 
    job.setJarByClass(GenerateGraphsJob.class); 

    configureJob(job); 

    int resultCode = job.waitForCompletion(true) ? 0 : 1; 

    return resultCode; 
} 

private void configureJob(Job job) throws IOException { 
    try { 
     Configuration config = getConf(); 
     Path inputPath = ConfigHelper.getChartInputPath(config); 
     Path outputPath = ConfigHelper.getChartOutputPath(config); 

     job.setInputFormatClass(AvroKeyInputFormat.class); 
     AvroKeyInputFormat.addInputPath(job, inputPath); 
     AvroJob.setInputKeySchema(job, StockReport.SCHEMA$); 


     job.setMapperClass(StockAverageMapper.class); 
     job.setCombinerClass(StockAverageCombiner.class); 
     job.setReducerClass(StockAverageReducer.class); 

     FileOutputFormat.setOutputPath(job, outputPath); 

    } catch (IOException | ClassCastException e) { 
     LOG.error("An job error has occurred.", e); 
    } 
} 

Mapper:.

public class StockAverageMapper extends 
     Mapper<AvroKey<StockReport>, NullWritable, StockYearSymbolKey, StockReport> { 
    private static Logger LOG = LoggerFactory.getLogger(StockAverageMapper.class); 

private final StockReport stockReport = new StockReport(); 
private final StockYearSymbolKey stockKey = new StockYearSymbolKey(); 

@Override 
protected void map(AvroKey<StockReport> inKey, NullWritable ignore, Context context) 
     throws IOException, InterruptedException { 
    try { 
     StockReport inKeyDatum = inKey.datum(); 
     for (Stock stock : inKeyDatum.getStocks()) { 
      updateKey(inKeyDatum, stock); 
      updateValue(inKeyDatum, stock); 
      context.write(stockKey, stockReport); 
     } 
    } catch (Exception ex) { 
     LOG.debug(ex.toString()); 
    } 
} 

Schema per chiave di uscita mappa:

{ 
    "namespace": "avro.model", 
    "type": "record", 
    "name": "StockYearSymbolKey", 
    "fields": [ 
    { 
     "name": "year", 
     "type": "int" 
    }, 
    { 
     "name": "symbol", 
     "type": "string" 
    } 
    ] 
} 

Stack trace:

java.lang.Exception: java.lang.IncompatibleClassChangeError: Found interface org.apache.hadoop.mapreduce.TaskAttemptContext, but class was expected 
    at org.apache.hadoop.mapred.LocalJobRunner$Job.runTasks(LocalJobRunner.java:462) 
    at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:522) 
Caused by: java.lang.IncompatibleClassChangeError: Found interface org.apache.hadoop.mapreduce.TaskAttemptContext, but class was expected 
    at org.apache.avro.mapreduce.AvroKeyInputFormat.createRecordReader(AvroKeyInputFormat.java:47) 
    at org.apache.hadoop.mapred.MapTask$NewTrackingRecordReader.<init>(MapTask.java:492) 
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:735) 
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:340) 
    at org.apache.hadoop.mapred.LocalJobRunner$Job$MapTaskRunnable.run(LocalJobRunner.java:243) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:745) 

Edit: Non che sia importante, ma sto lavorando per ridurre questo ai dati posso creare produzione JFreeChart da. Non passare attraverso il mapper in modo che non dovrebbe essere correlato.

risposta

6

Il problema è che org.apache.hadoop.mapreduce.TaskAttemptContext era un class in Hadoop 1 ma è diventato un interface in Hadoop 2.

Questo è uno dei motivi per cui le librerie che dipendono dalle librerie Hadoop devono avere file jar compilati separatamente per Hadoop 1 e Hadoop 2. Sulla base della traccia dello stack, sembra che in qualche modo si sia ottenuto un file jar Avro compilato da Hadoop1, nonostante sia in esecuzione con Hadoop 2.4.1.

Il download mirrors for Avro fornisce buoni downloadabili separati per avro-mapred-1.7.7-hadoop1.jar rispetto a avro-mapred-1.7.7-hadoop2.jar.

+0

Farò un tentativo. Queste classi Avro compilate funzionano con il mio altro lavoro. È proprio in questo lavoro che utilizza una libreria condivisa. Il mio pom ha 1.7.7 avro-mapred, avro-tools e avro. Ho compilato manualmente gli schemi avro con un jar chiamato avro-tools-1.7.7.jar. – Rig

+0

Hai inchiodato. Grazie. – Rig

1

Il problema è che Avro 1.7.7 supporta 2 versioni di Hadoop e quindi dipende da entrambe le versioni di Hadoop. E per impostazione predefinita i barattoli Avro 1.7.7 dipendono dalla vecchia versione di Hadoop. di costruire con Avro 1.7.7 con Hadoop2 basta aggiungere ulteriore linea classifier a Maven dipendenze:

<dependency> 
     <groupId>org.apache.avro</groupId> 
     <artifactId>avro-mapred</artifactId> 
     <version>1.7.7</version> 
     <classifier>hadoop2</classifier> 
    </dependency> 

questo vi dirà Maven per cercare avro-mapred-1.7.7-hadoop2.jar, non avro-mapred-1.7.7.jar

Stesso applicabile per Avro 1.7 .4 o superiore