2010-07-25 4 views
5

ho questo codice Java:Come riferimento sottoclassi di classi Java statiche con i generici a Scala

public class TestMapper extends AppEngineMapper<Key, Entity, NullWritable, NullWritable> { 
    public TestMapper() { 
    } 
// [... other overriden methods ...] 
     @Override 
     public void setup(Context context) { 
     log.warning("Doing per-worker setup"); 
     } 
} 

... che ho convertito a:

class TestMapper extends AppEngineMapper[Key, Entity, NullWritable, NullWritable] { 
// [... other overriden methods ...] 
     override def setup(context: Context) { 
     log.warning("Doing per-worker setup") 
     } 
} 

Ora il problema reale :

contesto è definito come un cl nidificato ass all'interno della classe org.apache.hadoop.mapreduce.Mapper:

 public static class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> { 
    //[... some other methods ...] 
protected void setup(org.apache.hadoop.mapreduce.Mapper<KEYIN,VALUEIN,KEYOUT,VALUEOUT>.Context context) throws java.io.IOException, java.lang.InterruptedException { /* compiled code */ } 
     public class Context extends org.apache.hadoop.mapreduce.MapContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT> { 

     public Context(org.apache.hadoop.conf.Configuration configuration, org.apache.hadoop.mapreduce.TaskAttemptID conf, org.apache.hadoop.mapreduce.RecordReader<KEYIN,VALUEIN> taskid, org.apache.hadoop.mapreduce.RecordWriter<KEYOUT,VALUEOUT> reader, org.apache.hadoop.mapreduce.OutputCommitter writer, org.apache.hadoop.mapreduce.StatusReporter committer, org.apache.hadoop.mapreduce.InputSplit reporter) throws java.io.IOException, java.lang.InterruptedException { /* compiled code */ } 

     } 

quindi non posso dire la mia classe Scala dove/cosa contesto è in realtà. Se Mapper non aveva farmaci generici ho potuto fare riferimento Contesto via

Mapper#Context 

ma come posso dire che Mapper ha Generics?

Mapper[_,_,_,_]#Context 

... non ha funzionato.

+1

Grazie mille per la domanda, ho trascorso diverse ore esattamente su queste classi! –

risposta

9

si deve fornire il tipo di base esatta per il vostro proiezioni tipo, nel tuo caso

Mapper[Key, Entity, NullWritable, NullWritable]#Context 

in modo preponderante setup sarebbe scritto come

override def setup(context: Mapper[Key, Entity, NullWritable, NullWritable]#Context) 

Uso può essere semplificata con l'introduzione di un tipo alias

class TestMapper extends AppEngineMapper[Key, Entity, NullWritable, NullWritable] { 

    type Context = Mapper[Key, Entity, NullWritable, NullWritable]#Context 

    override def setup(context: Context) = { 
     // ... 
    } 
} 

Se si desidera scrivere più mapper è possibile refactoring questo in un tratto che può essere miscelato nella vostra applicazione:

trait SMapper[A,B,C,D] extends Mapper[A,B,C,D] { 
    type Context = Mapper[A,B,C,D]#Context 
} 

class TestMapper extends AppEngineMapper[Key, Entity, NullWritable, NullWritable] 
        with SMapper[Key, Entity, NullWritable, NullWritable] { 
    override def setup(context: Context) = { 
    // ... 
    } 
} 

o per Hadoop semplice:

class TestMapper extends SMapper[Key, Entity, NullWritable, NullWritable] { 
    override def setup(context: Context) = { 
    // ... 
    } 
} 
+2

In realtà non è necessario il tipo esistenziale; poiché setup è un metodo di Mapper che viene sovrascritto, puoi semplicemente usare Mapper [A, B, C, D] #Context (o un alias di tipo) come suggerisci all'inizio. –

+0

Ho aggiunto alcune informazioni al mio OP che potrebbero delineare meglio il problema: * Il mapper è statico (se è importante ...) * Inoltre ho aggiunto l'intestazione della classe ... le tue prime soluzioni non l'hanno lavoro. Ho l'errore : nome scontro tra membro definito e ereditato: impostazione metodo: (contesto: TestMapper1.this.Ctx) Unità e metodo impostazione: (x $ 1: org.apache.hadoop.mapreduce.Mapper [KEYIN , VALUEIN, KEYOUT, VALUEOUT] #Context) L'unità nella classe AppEngineMapper ha lo stesso tipo dopo la cancellazione: (contesto: org.apache.hadoop.mapreduce.Mapper # Context) override def setup (context: Ctx) { Non sono sicuro di come applicare la terza soluzione (stesso errore) – Alex

+0

Grazie per la risposta, ma non ero in grado di compilare nessuno di questi soluzioni con lo stesso errore. –

0

Le persone hanno problemi a volte quando si utilizza la risposta accettata sono causa di un bug in Compilatore di Scala (link).

Problemi correlati