【发布时间】:2018-03-29 18:40:15
【问题描述】:
我需要在 Mapper 和 Reducer 之间传递 Enum Bucket 类型的列表,我已经根据 implementation-of-an-arraywritable-for-a-custom-hadoop-type 实现了自定义 BucketArrayWritable,并且 Bucket Enum 有一个无参数构造函数,但我总是得到错误
java.lang.RuntimeException: java.lang.NoSuchMethodException: Bucket.<init>()
at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:131)
at org.apache.hadoop.io.WritableFactories.newInstance(WritableFactories.java:58)
at org.apache.hadoop.io.WritableFactories.newInstance(WritableFactories.java:64)
at org.apache.hadoop.io.ArrayWritable.readFields(ArrayWritable.java:95)
at org.apache.hadoop.io.serializer.WritableSerialization$WritableDeserializer.deserialize(WritableSerialization.java:71)
at org.apache.hadoop.io.serializer.WritableSerialization$WritableDeserializer.deserialize(WritableSerialization.java:42)
at org.apache.hadoop.mapreduce.task.ReduceContextImpl.nextKeyValue(ReduceContextImpl.java:139)
at org.apache.hadoop.mapreduce.task.ReduceContextImpl.nextKey(ReduceContextImpl.java:114)
at org.apache.hadoop.mapreduce.lib.reduce.WrappedReducer$Context.nextKey(WrappedReducer.java:296)
at org.apache.hadoop.mapreduce.Reducer.run(Reducer.java:163)
at org.apache.hadoop.mapred.ReduceTask.runNewReducer(ReduceTask.java:610)
at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:444)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:449)
Caused by: java.lang.NoSuchMethodException: com.turn.platform.profile.mapreduce.counting.Bucket.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:125)
Reducer 可能想使用反射来初始化对象,但 Enum 构造函数默认是私有的,
8.9.2 Enum Body Declarations
在枚举声明中,没有访问修饰符的构造函数声明是私有的。
我不知道是不是因为 Hadoop ReflectionUtils 找不到私有构造函数
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.function.Predicate;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Writable;
public enum Bucket implements Writable{
// right bound exclusive
MAX((count) -> {
if (count > getValue()) {
return true;
}
return false;
}, (count, _userId, incre) -> {
value = count;
userId = _userId;
}),
TOTAL((count) -> {
return true;
}),
BUCKET_0_10((count) -> {
if (count < 10) {
return true;
}
return false;
}),
BUCKET_10_100((count) -> {
if (count >= 10 && count < 100) {
return true;
}
return false;
})
;
private static long value = 0;
private static LongWritable userId = new LongWritable(0);
private TriConsumer<Long, LongWritable, Long> consumer;
private Predicate<Long> predicator;
Bucket() {
}
Bucket(Predicate<Long> predicator) {
this.predicator = predicator;
}
Bucket(Predicate<Long> predicator, TriConsumer<Long, LongWritable, Long> consumer) {
this.consumer = consumer;
this.predicator = predicator;
}
public static long getValue() {
return value;
}
public static void setValue(long newVal) {
value = newVal;
}
public TriConsumer<Long, LongWritable, Long> getConsumer() {
if (consumer == null) {
consumer = (count, _userId, incre) -> {
setValue(getValue() + incre);
userId = _userId;
};
}
return consumer;
}
public Predicate<Long> getPredicator() {
return predicator;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeLong(value);
userId.write(out);
}
@Override
public void readFields(DataInput in) throws IOException {
value = in.readLong();
userId.readFields(in);
}
}
【问题讨论】:
标签: java hadoop reflection enums