2010-07-25 4 views
5

Je le code Java:Comment référencer sous-classes de classes Java statiques avec les génériques à 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"); 
     } 
} 

... que je suis converti à:

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

Maintenant, le problème réel :

Contexte est définie comme une cl imbriquée ass dans le org.apache.hadoop.mapreduce.Mapper classe: en fait

 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 */ } 

     } 

donc je ne peux pas dire ma classe Scala où/ce contexte est. Si Mapper avait pas de génériques que je pourrais faire référence à Contexte via

Mapper#Context 

mais comment puis-je dire que Mapper a Generics?

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

... ne fonctionne pas.

+1

Merci beaucoup pour la question, j'ai passé plusieurs heures sur ces cours! –

Répondre

9

Vous devez fournir le type exact de base pour votre projection de type, dans votre cas

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

donc primordial setup serait écrit comme

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

Utilisation peut être simplifiée par l'introduction d'un alias de type

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

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

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

Si vous souhaitez écrire plusieurs mappeurs vous pouvez factoriser cela en un trait qui peut être mélangé dans votre mise en œuvre:

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) = { 
    // ... 
    } 
} 

ou pour Hadoop plaine:

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

Vous n'avez pas réellement besoin du type existentiel; Puisque setup est une méthode de Mapper qui est en cours de remplacement, vous pouvez simplement utiliser Mapper [A, B, C, D] #Context (ou un alias de type) comme vous le suggérez au début. –

+0

J'ai ajouté quelques informations à mon OP qui peuvent mieux décrire le problème: * Mapper est statique (si c'est important ...) * J'ai aussi ajouté l'en-tête de la classe ... vos premières solutions didn ' t travail. J'ai erreur: nom de conflit entre membre défini et hérité: méthode d'installation: (contexte: TestMapper1.this.Ctx) Unité et configuration de la méthode: (x $ 1: org.apache.hadoop.mapreduce.Mapper [KEYIN , VALUEIN, KEYOUT, VALUEOUT] #Context) L'unité de la classe AppEngineMapper a le même type après l'effacement: (contexte: org.apache.hadoop.mapreduce.Mapper # Context) Unité override def setup (context: Ctx) { Je ne suis pas sûr de savoir comment appliquer la 3ème solution (même erreur) – Alex

+0

Merci de votre réponse, mais je n'ai pas pu compiler l'un de ces éléments solutions avec la même erreur. –

0

Les problèmes que les gens ont parfois lorsque vous utilisez la réponse acceptée sont dues à un bogue dans Compilateur Scala (link).

Questions connexes