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的源码有些出入.下面作个简单的记录,方便起见,引用自书本的语句都用斜体表 ...
随机推荐
- 【 D3.js 视频系列 】 飞速入门
本教程共包含 6 个视频,目的是为了帮助初学者快速入门,以便阅读本站其他文章. 本教程的名称为"飞速入门",是为初学者准备的,其中包括了 D3 开发中最基础的知识.对 D3 掌握得 ...
- Java [Leetcode 111]Minimum Depth of Binary Tree
题目描述: Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along th ...
- B树索引和位图索引的区别!
B树索引主键和唯一性约束字段的B树索引,效率几乎和海量数据没有关系. 键值重复率低的字段比较适合使用B树索引. 位图索引键值重复率高的字段比较适合使用位图索引.count.and.or.in这些特定的 ...
- 安装oracle XML Database 组件
近期部署项目数据库,编译包时遇到错误: PACKAGE CTG.CTG_CSB_COMMON 编译错误 错误:PLS-00201: identifier 'XMLDOM' must be dec ...
- “自私”的Linux
导读 “如果当时我真的知道从头建立一个操作系统的难度,肯定是不会有勇气去做的.”1991年8月25日,随着林纳斯·托瓦兹(Linus Torvalds)这句“天真”的描述,Linux系统正式与世人见面 ...
- Storm-6 Storm的并行度、Grouping策略以及消息可靠处理机制简介
概念: 配置并行度 动态的改变并行度 流分组策略----Stream Grouping 消息的可靠处理机制 概念: Workers (JVMs): 在一个节点上可以运行一个或多个独立的JVM 进程.一 ...
- [OFBiz]开发 三
1. Debug不要在Eclipse中使用Ant来启动ofbiz, 因为在Eclipse中无法kill掉Ant的进程,而ofbiz又没有提供stop的方法.(有一个hook shutdown的方法,但 ...
- 用javascript 面向对象制作坦克大战(三)
之前,我们完成了坦克的移动和地图的绘制,这次我们来完成碰撞检测和炮弹的发射. 上代码前来张最新的类图: 3. 碰撞检测 前面我们已经完成了坦克的移动和地图的绘制,下面我们开始写碰撞检测. 3. ...
- Extjs Ext.onReady的用法
最近在学习Extjs,当然首先学习的肯定是从官网下载下来的example. 从学习上而言对于Extjs,我个人认同的是李林峰老师所言先从视图开始,搞一些所见即所得的东西. 废话有点多,对于Extjs而 ...
- Qt加载网页(加载浏览器插件)和制作托盘后台运行(南信大财务报账看号)
程序模块要添加QNetWork和QWebKit模块: nuistfinancevideo.h文件: #ifndef NUISTFINANCEVIDEO_H #define NUISTFINANCEVI ...