自定义WritableComparable遭遇空指针异常的一个场景

自定义的WritableComparable中,如下代码一切ok:

......
private String cookieID;
......
public MyWritable()
{}

public MyWritable(final String cookieID)
{
	set(cookieID);
}

public void set(final String cookieID)
{
	this.cookieID = cookieID;
}
public void write(final DataOutput out) throws IOException
{
	out.writeUTF(this.cookieID);
}
public void readFields(final DataInput in) throws IOException
{
    this.cookieID = in.readUTF();
}

但是如果修改为:

......
private Text cookieID;
......
public void set(final String cookieID)
{
	this.cookieID = new Text(cookieID);
}
public void write(final DataOutput out) throws IOException
{
	this.cookieID.write(out);
}
public void readFields(final DataInput in) throws IOException
{
    this.cookieID.readFields(in);
}

则报错:
java.lang.NullPointerException
at com.***.MyWritable.readFields(MyWritable.java:75)
at org.apache.hadoop.io.WritableComparator.compare(WritableComparator.java:158)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.compare(MapTask.java:1265)
at org.apache.hadoop.util.QuickSort.sortInternal(QuickSort.java:74)
at org.apache.hadoop.util.QuickSort.sort(QuickSort.java:63)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:1595)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.flush(MapTask.java:1482)
at org.apache.hadoop.mapred.MapTask$NewOutputCollector.close(MapTask.java:720)
at org.apache.hadoop.mapred.MapTask.closeQuietly(MapTask.java:2014)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:794)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:168)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1614)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:163)

初始以为这是一个很奇怪的问题,调试了半天,才发现原因很简单,就是因为类构造时,没有初始化cookieID所致。按下列方法修改就行了:

private Text cookieID=new Text(); //或在默认构造函数中实例该变量

回头一想,觉得自己真笨......本来很简单的问题,从错误提示已经看到是空指针的原因了,也曾怀疑“final DataInput in”是否为空,并还调试后排除了这个可能性,怎么就没有很快的想到可能是cookieID为空呢?

小结一下:

1. 自定义的WritableComparable,使用时,调用者首先会初始化该类对象。在write场景下,对象的成员变量一般由外部set得到(例如上面代码中的set方法),所以即使没有初始化,也不会报空指针异常。但是read场景下,缺失了set环节,所以readFields时,没有初始化的对象成员变量仍然为null,所以会报空指针异常。

2. 为何String不存在这个问题呢?其实基本数据类型都不存在这个问题,看来是hadoop对基本类型已经做处理了。

3. 看来初始化类成员变量是个好习惯呀,否则后患无穷......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值