标签:
问题描述:
在hadoop中处理多个文件,其中每个文件一个map。
我使用的方法为生成一个文件,文件中包含所有要压缩的文件在HDFS上的完整路径。每个map 任务获得一个路径名作为输入。
在eclipse中调试时,map中处理hdfs上的文件用到的FileSystem对象为整个class中的静态成员变量,在eclipse中运行没有错误,打包成jar提交到集群运行,就会在map函数中
FileStatus fileStatus = tmpfs.getFileStatus(inputdir);
这一句报错java.lang.NullPointerException 卡了2天,不知到是哪错了。
昨天下午才想到应该
是
tmpfs是一个空对象,没有赋值。
虽然tmpfs 在最外层的类中声明为静态变量,并且在main函数中有赋值,然而在map函数内还是NullPointer。
tmpfs赋值就解决了问题。
之后改为在map函数内部给
这也验证了eclipse中调试运行程序是在本地运行,只不过是调用了hadoop的类库,在8088端口的监控网页上也看不到提交应用的信息。
必须打包成jar,用bin/hadoop jar运行才能真正提交到集群运行。而且main函数内部初始化的静态变量,在map中还是未初始化状态,猜测是集群上运行的map任务,和本地的main函数是互相独立的关系。
改正后的代码:
1 @Override 2 public void map(Object key, Text value, 3 Context context) 4 throws 5 IOException, InterruptedException { 6 Configuration conf = context. getConfiguration(); 7 FileSystem tmpfs = FileSystem.get(URI.create("hdfs://192.168.2.2:9000"), conf); 8 9 Path inputdir = new Path(value.toString()); //获取待处理的文件的Path对象 10 FileStatus fileStatus = tmpfs.getFileStatus(inputdir); 11 12 //做相应处理 13 14 context.write(new Text(value.toString()), new Text(" ")); 15 }
Configuration conf = context. getConfiguration();//通过context获取job中配置的Configuration对象
FileSystem tmpfs = FileSystem.get(URI.create("hdfs://192.168.2.2:9000"), conf); //需要在map函数内部赋值
附录:
例如这样一个问题,在集群上压缩(zipping)一些文件,你可以使用以下几种方法:
FileOutputFormat.setCompressOutput(conf, true); FileOutputFormat.setOutputCompressorClass(conf, org.apache.hadoop.io.compress.GzipCodec.class); conf.setOutputFormat(NonSplitableTextInputFormat.class); conf.setNumReduceTasks(0);
public void map(WritableComparable key, Writable value, OutputCollector output, Reporter reporter) throws IOException { output.collect((Text)value, null); }
[hadoop] map函数中使用FileSystem对象出现java.lang.NullPointerException的原因及解决办法
标签:
原文地址:http://www.cnblogs.com/scw2901/p/4331605.html