Reputation: 960
I'm new to hadoop. I'm trying to send, 2 float arguments to the reducer in the following code.mapper passing the arguments to reducer successfully but if i start running the reducer null pointer exception thrown.. can any one please help me out. thanks in advance.
public class MaxTemperature extends Configured implements Tool {
public static class MapMapper extends Mapper<LongWritable, Text, Text, PairWritable>{
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException{
String regex = ",";//''single quote not applicable for comma.
String[] val = value.toString().split(regex);
FloatWritable[] vv = new FloatWritable[2];
vv[0]= new FloatWritable(Float.parseFloat(val[3]));
vv[1]=new FloatWritable(Float.parseFloat(val[13]));
float dd=Float.parseFloat(val[3]);
PairWritable ddd = new PairWritable();
context.write(new Text(val[2]), ddd.set(vv[0], vv[1]));
}
}
public static class PairWritable extends ArrayWritable implements Writable{
public PairWritable() {
super(FloatWritable.class);
// TODO Auto-generated constructor stub
}
private FloatWritable floatone;
private FloatWritable floattwo;
public String toString() {
String s = Float.toString(floatone.get());
String a=Float.toString(floattwo.get());
String q = s+'\t'+a;
return q;
}
public void set(float f1, float f2){
FloatWritable ff1 = new FloatWritable(f1);
FloatWritable ff2 = new FloatWritable(f1);
set(ff1, ff2);
}
public PairWritable set(FloatWritable f1, FloatWritable f2){
this.floatone=f1;
this.floattwo=f2;
return this;
}
public float getone(){
return floatone.get();
}
public float gettwo(){
return floattwo.get();
}
public void write(DataOutput out) throws IOException {
// TODO Auto-generated method stub
this.floatone.write(out);
this.floattwo.write(out);
}
public void readFields(DataInput in) throws IOException {
// TODO Auto-generated method stub
this.floatone.readFields(in);
this.floattwo.readFields(in);
}
}
public static class Mapreducers extends Reducer<Text,PairWritable, Text,PairWritable>{
public void reduce(Text key, Iterable<PairWritable> values,Context context) throws IOException, InterruptedException{
float sumone =0;
float sumtwo=0;
for(PairWritable dd: values){
sumone+=dd.getone();
sumtwo+=dd.gettwo();
}
FloatWritable result1 = new FloatWritable(sumone);
FloatWritable result2 = new FloatWritable(sumtwo);
PairWritable ddd = new PairWritable();
context.write(key, ddd.set(result1, result2));
}
}
public int run(String[] args) throws Exception {
Job job = new Job();
job.setJarByClass(MaxTemperature.class);
job.setJobName("MaxTemperature");
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(args[0]), conf);
if(fs.exists(new Path(args[1]))){
fs.delete(new Path(args[1]),true);
}
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.setMapperClass(MapMapper.class);
//job.setCombinerClass(Mapreducers.class);
//job.setNumReduceTasks(0);
job.setReducerClass(Mapreducers.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(PairWritable.class);
return job.waitForCompletion(true)?0:1;
}
public static void main(String[] args) throws Exception{
int xx =1;
xx = ToolRunner.run(new MaxTemperature(), args);
System.exit(xx);
}
}
Upvotes: 1
Views: 250
Reputation: 1502646
I suspect the problem is simply that on deserialization, nothing is populating the floatone
and floattwo
fields. You're trying to populate the data within objects that don't exist. This:
public void readFields(DataInput in) throws IOException {
this.floatone.readFields(in);
this.floattwo.readFields(in);
}
should probably be:
public void readFields(DataInput in) throws IOException {
floatone = new FloatWritable();
floattwo = new FloatWritable();
floatone.readFields(in);
floattwo.readFields(in);
}
Alternatively, change both write
and readFields
:
public void write(DataOutput out) throws IOException {
out.writeFloat(floatone.get());
out.writeFloat(floattwo.get());
}
public void readFields(DataInput in) throws IOException {
floatone = new FloatWritable(in.readFloat());
floattwo = new FloatWritable(in.readFloat());
}
That looks clearer and potentially more efficient to me.
Upvotes: 2