Lorsque j'exécute un fichier .jar Hadoop à partir de l'invite de commande, une exception est générée, indiquant que la méthode StockKey n'est pas utilisée.
StockKey est ma classe personnalisée définie pour mon propre type de clé.
Voici l'exception:
12/07/12 00:18:47 INFO mapred.JobClient: Task Id :
attempt_201207082224_0007_m_000000_1, Status : FAILED
Java.lang.RuntimeException: Java.lang.NoSuchMethodException: SecondarySort$StockKey.
<init>()
at org.Apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.Java:115)
at org.Apache.hadoop.io.WritableComparator.newKey(WritableComparator.Java:109)
at org.Apache.hadoop.io.WritableComparator.<init>(WritableComparator.Java:95)
at org.Apache.hadoop.io.WritableComparator.get(WritableComparator.Java:51)
at org.Apache.hadoop.mapred.JobConf.getOutputKeyComparator(JobConf.Java:795)
at org.Apache.hadoop.mapred.MapTask$MapOutputBuffer.<init>(MapTask.Java:817)
at org.Apache.hadoop.mapred.MapTask.runOldMapper(MapTask.Java:383)
at org.Apache.hadoop.mapred.MapTask.run(MapTask.Java:325)
at org.Apache.hadoop.mapred.Child$4.run(Child.Java:270)
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:1127)
at org.Apache.hadoop.mapred.Child.main(Child.Java:264)
Vous devez fournir un constructeur par défaut vide dans votre classe de clés. Hadoop utilise la réflexion et ne peut deviner aucun paramètre à alimenter.
Il suffit donc d’ajouter le constructeur par défaut:
public StockKey(){}
Il y a une autre chose à vérifier lorsque vous obtenez des erreurs comme celle-ci pour les classes qui sont en écriture, les mappeurs, les réducteurs, etc.
Si la classe est une classe intérieure , assurez-vous qu’elle est déclarée static
(c’est-à-dire qu’elle n’a pas besoin d’une instance de la classe englobante). Sinon, Hadoop ne pourra pas instancier votre classe interne et donnera la même erreur: un constructeur zéro argument est nécessaire.
Pour scala aussi , j'ai résolu le problème en ajoutant le constructeur par défaut comme ci-dessous,
class IntPair (first : IntWritable, second : IntWritable) extends WritableComparable[IntPair] {
def this() = this(first = new IntWritable(), second = new IntWritable())
def getFirst () : IntWritable = {
first
}
def getSecond () : IntWritable = {
second
}
}
Assurez-vous que vous avez le constructeur par défaut, mais je devais aussi ajouter le mot clé static
à ma déclaration de classe. C'est,
public class SecondarySort {
public static void main(String[] args) {...}
public static class StockKey extends ... {}
}
A été confronté à ce même problème. Fixé par les pointeurs suivants de @Thomas et @Chris.
On dirait que ces deux solutions sont nécessaires pour résoudre le problème:
La réponse de @Thomas est requise, car Hadoop utilise la réflexion et construit de grands projets.
Une réponse de @Chris est requise pour utiliser des classes internes et appeler des mappeurs/réducteurs à partir de main ().
Aucune réponse ne m'a aidé.
Dans mon cas, cela est arrivé lorsque la visibilité du constructeur a été réduite par erreur ou rapidement.
Par exemple. le constructeur parent est public et celui de la classe héritée est default ou protected!