Hadoop on Mac with IntelliJ IDEA - 3 解决MRUnit - No applicable class implementing Serialization问题
本文讲述在IntelliJ IDEA中使用MRUnit 1.0.0测试Mapper派生类时因MapDriver.withInput(final K1 key, final V1 val)的key参数被错误设置成空字符串""导致No applicable class implementing Serialization的解决过程。
环境:Mac OS X 10.9.5, IntelliJ IDEA 13.1.4, Hadoop 1.2.1, MRUnit 1.0.0
Hadoop放在虚拟机中,宿主机通过SSH连接,IDE和数据文件在宿主机。IDEA自身运行于JDK 1.8,IDEA工程及Hadoop使用JDK 1.6。
这是个粗心的错误。
操作代码如下:
@SuppressWarnings("all")
public class MapDriverTest {
private Mapper mapper;
private MapDriver driver;
@Before
public void init() {
mapper = new TextMapper();
driver = new MapDriver(mapper);
}
@Test
public void test() {
String content = "This is a simple test for TextMapper created by Michael";
try {
driver.withInput("", new Text(content))
.withOutput(new Text("this"), new IntWritable(1))
.withOutput(new Text("is"), new IntWritable(1))
.withOutput(new Text("a"), new IntWritable(1))
.withOutput(new Text("simple"), new IntWritable(1))
.withOutput(new Text("test"), new IntWritable(1))
.withOutput(new Text("for"), new IntWritable(1))
.withOutput(new Text("TextMapper"), new IntWritable(1))
.withOutput(new Text("created"), new IntWritable(1))
.withOutput(new Text("by"), new IntWritable(1))
.withOutput(new Text("Michael"), new IntWritable(1))
.runTest();
} catch (IOException e) {
e.printStackTrace();
}
}
}
相关类代码如下:
public class TextMapper extends Mapper<Object, Text, Text, IntWritable> {
final IntWritable count = new IntWritable(1);
final Text text = new Text();
@Override
protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer tokenizer = new StringTokenizer(value.toString());
while (tokenizer.hasMoreTokens()) {
text.set(tokenizer.nextToken());
context.write(text, count);
}
}
}
执行结果如下:

设置成""是完成参考别人代码写的,所以我不知如此设置的原因,原因是Hadoop有一套专用数据类型,分别映射了java基本类型,这里设置成""将被当成设置为String类型,在序列化时因不是Hadoop的数据类型,因而报错(更新于2014.10.06)。下面描述解决过程。
第一步,对比了参考代码,无拼写错误。
第二步,第一次使用MRUnit,Hadoop也刚学习,没人指导,纯抓瞎。只能先验证测试代码本身能否跑起来。注释掉MapDriverTest.test()中driver调用部分,并在init()及test()、TextMapper的map(args)中加入日志,看看代码执行到哪里报错。主体代码示意如下:
MapDriverTest
@Before
public void init() {
System.out.println("init BEGIN");
mapper = new TextMapper();
driver = new MapDriver(mapper);
System.out.println("init END");
} @Test
public void test() {
System.out.println("test BEGIN");
String content = "This is a simple test for TextMapper created by Michael";
/*try {
driver.withInput("", new Text(content))...*/
System.out.println("test END");
}
TextMapper
@Override
protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
String keyString = key == null ? "null" : key.toString();
String valueString = value == null ? "null" : value.toString();
String invokeString = "map(key = " + keyString +
", value = " + valueString + ") BEGIN";
System.out.println(invokeString);
StringTokenizer tokenizer = new StringTokenizer(value.toString());
while (tokenizer.hasMoreTokens()) {
System.out.println("while RUN");
text.set(tokenizer.nextToken());
context.write(text, count);
}
System.out.println("map END");
}
按预期,还没调用driver.run()或runtTest(),则TextMapper的map方法日志不会输出。现在执行,输出如下
init BEGIN
init END
test BEGIN
test END
符合预期,测试代码运行正常。
第三步,恢复test方法至上一版本,特别处理driver.withInput的输入参数,为key及value传入相同的值,观察运行结果。新代码如下:
@Test
public void test() {
System.out.println("test BEGIN");
String content = "This is a simple test for TextMapper created by Michael";
try {
//driver.withInput("", new Text(content))
driver.withInput(new Text(content), new Text(content)) // pass the same params to withInput, see how it acts.
.withOutput(new Text("This"), new IntWritable(1))
.withOutput(new Text("is"), new IntWritable(1))
.withOutput(new Text("a"), new IntWritable(1))
.withOutput(new Text("simple"), new IntWritable(1))
.withOutput(new Text("test"), new IntWritable(1))
.withOutput(new Text("for"), new IntWritable(1))
.withOutput(new Text("TextMapper"), new IntWritable(1))
.withOutput(new Text("created"), new IntWritable(1))
.withOutput(new Text("by"), new IntWritable(1))
.withOutput(new Text("Michael"), new IntWritable(1))
.runTest();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("test END");
}
按资料说明,key参数表示每行的字节偏移量[1]。之前传入"",现在传入与value相同的值,不要位置数据了。走一个,看看啥情况。似乎成功了,看图。

现在,可以认定是key传递""导致的错误了。
再做一次调整,传递key = new Text(),观察执行结果。

通过了。
什么,你要试试传递key = null。会报错的。另外,日志打印用的key == null ? "null" : key.toString()语句,意义不大,因为传递null会导致java.lang.NullPointerException。网上的资料好多是传递null的,我这边测试会报空指向异常。怀疑是RMUnit版本问题。
第一次使用RMUnit,遇到这个问题,即使目前不知原因,但还是勉强跑起来了,继续尝试。
参考
[1]Chuck Lam. Hadoop In Action. Manning Publications. 2010
Hadoop on Mac with IntelliJ IDEA - 3 解决MRUnit - No applicable class implementing Serialization问题的更多相关文章
- Hadoop on Mac with IntelliJ IDEA - 7 解决failed to report status for 600 seconds. Killing!问题
本文讲述作业在Hadoop 1.2.1完成map后ruduce阶段遇到failed to report status for 600 seconds. Killing!问题的解决过程. 环境:Mac ...
- Hadoop on Mac with IntelliJ IDEA - 1 解决input path does not exist问题
本文讲述使用IntelliJ IDEA时遇到Hadoop提示input path does not exist(输入路径不存在)的解决过程. 环境:Mac OS X 10.9.5, IntelliJ ...
- Hadoop on Mac with IntelliJ IDEA - 6 解决KeyValueTextInputFormat读取时只有key值问题
本文讲述使用KeyValueTextInputFormat在Hadoop 0.x正常工作.Hadoop 1.2.1失效的解决过程. 环境:Mac OS X 10.9.5, IntelliJ IDEA ...
- Hadoop on Mac with IntelliJ IDEA - 5 解决java heap space问题
本文讲述在CentOS 6.5中提交作业到hadoop 1.2.1于reduce阶段遇到Error: java heap space错误导致作业重新计算的解决过程.解决办法适用Linux.Mac OS ...
- Hadoop on Mac with IntelliJ IDEA - 2 解决URI错误导致Permission denied
本文讲述在IntelliJ IDEA中使用FileSystem.copyFromLocalFile操作Hadoop时因URI格式有误导致Permission denied的解决过程. 环境:Mac O ...
- Hadoop on Mac with IntelliJ IDEA - 9 解决Type mismatch in value from map问题
修改陆喜恒. Hadoop实战(第2版)5.3排序的代码时遇到IO异常. 环境:Mac OS X 10.9.5, IntelliJ IDEA 13.1.5, Hadoop 1.2.1 异常具体信息如下 ...
- Hadoop on Mac with IntelliJ IDEA - 8 单表关联NullPointerException
简化陆喜恒. Hadoop实战(第2版)5.4单表关联的代码时遇到空指向异常,经分析是逻辑问题,在此做个记录. 环境:Mac OS X 10.9.5, IntelliJ IDEA 13.1.5, Ha ...
- Hadoop on Mac with IntelliJ IDEA - 4 制作jar包
本文讲述使用IntelliJ IDEA打包Project的过程,即,打jar包. 环境:Mac OS X 10.9.5, IntelliJ IDEA 13.1.4, Hadoop 1.2.1 Hado ...
- Hadoop on Mac with IntelliJ IDEA - 10 陆喜恒. Hadoop实战(第2版)6.4.1(Shuffle和排序)Map端 内容整理
下午对着源码看陆喜恒. Hadoop实战(第2版)6.4.1 (Shuffle和排序)Map端,发现与Hadoop 1.2.1的源码有些出入.下面作个简单的记录,方便起见,引用自书本的语句都用斜体表 ...
随机推荐
- noip2000提高组题解
事实再次向我证明了RP的重要性... 第一题:进制转换 是我最没有把握AC的一道题目却是我唯一一道AC的题目,真是讽刺.看完题目几乎完全没有往正常的解法(取余倒序)去想,直接写了搜索,因为数据范围在2 ...
- 【CSS】css各种居中方法
水平居中的text-align:center 和 margin:0 auto 这两种方法都是用来水平居中的,前者是针对父元素进行设置而后者则是对子元素.他们起作用的首要条件是子元素必须没有被flo ...
- 【又见LCS】NYOJ-37 回文字符串
[题目链接] 回文字符串 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba& ...
- wifi详解(一)
1 WLAN技术 WLAN是英文WirelessLAN的缩写,就是无线局域网的意思.无线以太网技术是一种基于无线传输的局域网技术,与有线网络技术相比,具有灵活.建网迅速.个人化等特点.将 ...
- HDU 5876 Sparse Graph
Sparse Graph Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)To ...
- How to enable DateTimePicker to use both date and time z
Recently in one of my project I needed to have an option to display the DateTimePicker allowing user ...
- E asy Boo t 6.51 启动易 制作启动光盘的软件(附注册码)
内建ISO文件生成器,可直接生成可启动ISO文件,并支持N合1优化. -------中文版注册码------- 用户名:中华人民共和国 注册码:2898-5448-5603-BB2D -------英 ...
- 《转》DNS放大攻击
原文链接:http://blog.sina.com.cn/s/blog_90bb1f200101iazl.html 放大攻击(也称为杠杆攻击,英文名字DNS Amplification Attack) ...
- Unity中Instantiate一个prefab时需要注意的问题
在调用Instantiate()方法使用prefab创建对象时,接收Instantiate()方法返回值的变量类型必须和声明prefab变量的类型一致,否则接收变量的值会为null. 比如说,我在 ...
- 百家搜索:在网站中添加Google、百度等搜索引擎
来源:http://www.ido321.com/1143.html 看到一些网站上添加了各种搜索引擎.如Google.百度.360.有道等,就有点好奇,这个怎么实现?研究了一各个搜索引擎怎么传送关键 ...