Ответ 1
Вы должны указать пустой конструктор по умолчанию в своем ключевом классе. Hadoop использует отражение, и он не может угадать параметры для подачи.
Поэтому просто добавьте конструктор по умолчанию:
public StockKey(){}
Когда я запускаю файл Hadoop.jar из командной строки, он генерирует исключение, не указывающее такой метод StockKey метода.
StockKey - это мой пользовательский класс, определенный для моего собственного типа ключа.
Вот исключение:
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)
Вы должны указать пустой конструктор по умолчанию в своем ключевом классе. Hadoop использует отражение, и он не может угадать параметры для подачи.
Поэтому просто добавьте конструктор по умолчанию:
public StockKey(){}
Еще одна вещь, которую нужно проверить при получении таких ошибок для классов, которые являются записываемыми, картографами, редукторами и т.д.
Если класс является внутренним классом, убедитесь, что он объявлен static
(т.е. не нужен экземпляр входящего класса). В противном случае Hadoop не сможет создать экземпляр вашего внутреннего класса и даст такую же ошибку - нужен конструктор с нулевым аргументом.
Для scala тоже, я исправил проблему с добавлением конструктора по умолчанию, как показано ниже,
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
}
}
Никакой ответ не помог мне.
В моем случае это произошло, когда я уменьшил видимость конструктора по ошибке или спешил.
например. родительский конструктор является общедоступным и унаследованным классом один по умолчанию или защищен!
Столкнулся с этой же проблемой. Исправлено следующими указателями от @Thomas и @Chris.
Похоже, что оба решения необходимы для решения проблемы:
Ответ от @Thomas требуется, поскольку Hadoop использует отражение и при создании больших проектов.
Ответ от @Chris требуется при использовании внутренних классов и вызове Mappers/Reducers из main().