2014-06-06 2 views
1

내가 하둡과 자바 초보자 오전, 내가지도를 작성하고는, 근접에 따라 그룹으로 함께 위도와 경도의 집합을 클러스터링 기능을 감소하고, (북의 수를 크기를 설정 클러스터 긴 쌍) 지금 현재로 대표 위도, 긴 쌍 (, 그것은 최초의 위도, 긴 쌍 발생의)널 포인터 예외 - 하둡 맵리 듀스 작업

다음

내 코드입니다 :.

package org.myorg; 

import java.io.IOException; 
import java.util.*; 

import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.conf.*; 
import org.apache.hadoop.io.*; 
import org.apache.hadoop.mapreduce.*; 
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; 
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; 
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; 

import util.hashing.*; 



public class LatLong { 


public static class Map extends Mapper<Object, Text, Text, Text> { 
    //private final static IntWritable one = new IntWritable(1); 


    public void map(Object key, Text value, Context context) throws IOException, InterruptedException { 
     String line = value.toString(); 
     String[] longLatArray = line.split(","); 
     double longi = Double.parseDouble(longLatArray[0]); 
     double lat = Double.parseDouble(longLatArray[1]); 
     //List<Double> origLatLong = new ArrayList<Double>(2); 
     //origLatLong.add(lat); 
     //origLatLong.add(longi); 
     Geohash inst = Geohash.getInstance(); 
     //encode is the library's encoding function 
     String hash = inst.encode(lat,longi); 
     //Using the first 5 characters just for testing purposes 
     //Need to find the right one later 
     int accuracy = 4; 
     //hash of the thing is shortened to whatever I figure out 
     //to be the right size of each tile 
     Text shortenedHash = new Text(hash.substring(0,accuracy)); 
     Text origHash = new Text(hash); 
     context.write(shortenedHash, origHash); 
    } 
} 

public static class Reduce extends Reducer<Text, Text, Text, Text> { 

    private IntWritable totalTileElementCount = new IntWritable(); 
    private Text latlongimag = new Text(); 
    private Text dataSeparator = new Text(); 

    @Override 
    public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { 
     int elementCount = 0; 
     boolean first = true; 
     Iterator<Text> it= values.iterator(); 
     String lat = new String(); 
     String longi = new String(); 
     Geohash inst = Geohash.getInstance(); 

     while (it.hasNext()) { 
     elementCount = elementCount+1; 
     if(first) 
     { 
      lat = Double.toString((inst.decode(it.toString()))[0]); 
      longi = Double.toString((inst.decode(it.toString()))[1]); 
      first = false; 

     } 
     @SuppressWarnings("unused") 
     String blah = it.next().toString(); 


     } 
     totalTileElementCount.set(elementCount); 
     //Geohash inst = Geohash.getInstance(); 

     String mag = totalTileElementCount.toString(); 

     latlongimag.set(lat+","+ longi +","+mag+","); 
     dataSeparator.set(""); 
     context.write(latlongimag, dataSeparator); 
    } 
} 

public static void main(String[] args) throws Exception { 
    Configuration conf = new Configuration(); 
    Job job = new Job(conf, "wordcount"); 
    job.setJarByClass(LatLong.class); 

    job.setOutputKeyClass(Text.class); 
    job.setOutputValueClass(Text.class); 

    job.setMapperClass(Map.class); 
    job.setReducerClass(Reduce.class); 

    job.setInputFormatClass(TextInputFormat.class); 
    job.setOutputFormatClass(TextOutputFormat.class); 

    FileInputFormat.addInputPath(job, new Path(args[0])); 
    FileOutputFormat.setOutputPath(job, new Path(args[1])); 

    job.waitForCompletion(true); 
} 

} 

나는 NPE 받고 있어요 . 어떻게 테스트 할 수 있을지 모르겠다. 코드에서 오류를 찾을 수 없다.

하둡 오류 : geohash와 라이브러리에서

java.lang.NullPointerException 
    at util.hashing.Geohash.decode(Geohash.java:41) 
    at org.myorg.LatLong$Reduce.reduce(LatLong.java:67) 
    at org.myorg.LatLong$Reduce.reduce(LatLong.java:1) 
    at org.apache.hadoop.mapreduce.Reducer.run(Reducer.java:176) 
    at org.apache.hadoop.mapred.ReduceTask.runNewReducer(ReduceTask.java:663) 
    at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:426) 
    at org.apache.hadoop.mapred.Child$4.run(Child.java:255) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at javax.security.auth.Subject.doAs(Subject.java:396) 
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1132) 
    at org.apache.hadoop.mapred.Child.main(Child.java:249) 

디코드 기능은 두 배의 배열을 반환합니다. 모든 포인터가 크게 감사하겠습니다! 시간 내 줘서 고마워! . 나는() 문제가 it.next있을 필요가 있다는 사실을 깨달았다 toString() 기능을 감소에서가 아니라 단지 it.toString 한

:

EDIT1 (테스트 후) 나는이 변화를 만들어 시험했을 때()하지만,이 오류가있어, 나는 내가 while 루프 조건에서 hasnext()를 확인하고 때 올해야하는 이유를 모르겠어요.

java.util.NoSuchElementException: iterate past last value 
    at org.apache.hadoop.mapreduce.ReduceContext$ValueIterator.next(ReduceContext.java:159) 
    at org.myorg.LatLong$Reduce.reduce(LatLong.java:69) 
    at org.myorg.LatLong$Reduce.reduce(LatLong.java:1) 
    at org.apache.hadoop.mapreduce.Reducer.run(Reducer.java:176) 
    at org.apache.hadoop.mapred.ReduceTask.runNewReducer(ReduceTask.java:663) 
    at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:426) 
    at org.apache.hadoop.mapred.Child$4.run(Child.java:255) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at javax.security.auth.Subject.doAs(Subject.java:396) 
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1132) 
    at org.apache.hadoop.mapred.Child.main(Child.java:249) 

EDIT2 (추가 시험) : 솔루션

내가 it.next을 (전화 드렸습니다는) 두 번 이상, 반복자 인을, 그것은 단지 두 번이 진행됩니다, 마지막에 반복, 그것은 조건을 확인하고 입력,하지만 난 후 하나의 다음 요소가있는 한 문제가 발생하는, 두 번 it.next()를 호출하고 있습니다 (마지막 하나.)

+0

난 그냥 작은 자바 지식을 가지고. u는 당신의 예외 검색 영역을 좁힐 시도 할 수 있다면 우리는 내가 분석 할 때 –

+0

그래서,이 오류가 아마 디코드 it.toString이의이 돼있 작동하지 않는 것을 의미 널 포인터를 반환한다는 것을 의미 더 도움이 시도 할 수 있습니다. 이 반복자 클래스의 내 사용이 잘못, 또는 감속기에 공급되는 데이터 자체 null의 경우, 어느 의미합니다.그러나 매퍼는 실제로 null이 아닌 값으로 orighash를 제공합니다. – aishpr

+0

전에 hadoop을 사용하지는 않았지만 ..에 관해서는 잘 읽으십시오. 자바는 시간에 따라 걱정됩니다. * 수동으로 데이터를 반복 해보십시오. * 테스트로 하나의 단일 레코드로 실행하십시오. test * test 'security'issues –

답변

1

당신은 여전히, it 대신 it.next()toString 전화, 그래서 당신은 하나 개의 while 반복에서 it.next() 두 번 호출 때문에 그것을 inst.decode(it.next().toString())하지 마십시오

String cords = it.next().toString(); 
lat = Double.toString((inst.decode(cords))[0]); 
longi = Double.toString((inst.decode(cords))[1]); 

lat = Double.toString((inst.decode(it.toString()))[0]); 
longi = Double.toString((inst.decode(it.toString()))[1]); 

을 변경해야합니다 .

String blah = it.next().toString();은 위와 같은 이유 때문에 java.util.NoSuchElementException: iterate past last value이되므로 전화하지 마십시오.

그리고 당신은 first = false의 경우에 당신이 if(first)를 입력 결코 String cords = it.next().toString(); 를 호출하지 그래서 it.hasNext() 항상 true를 반환하고 while 루프를 떠나지 않을 것입니다, 그래서 적절한 조건문을 추가 할 것을 기억 String blah = it.next().toString();을 제거 할 때.

+0

답변 해 주셔서 감사합니다. 나는 그것을 언젠가 되돌려 놓고 그것을 달렸다. 그리고 그 일은 51 %를 줄 였으므로 다음 질문을 던진다. http://stackoverflow.com/questions/24089330/hadoop-maoreduce-job-stuck-at-map-100-reduce -51 – aishpr

0

이 의미 중 하나를 당신의 "그것" 그렇지 않은 경우 디코딩 후 null이 반환됩니다. null 체크를합니다.

+0

그래서, 실제로 it.next(). toString()을 사용해야한다는 것을 깨달았습니다. 단지 'it'이 아니라 사용할 필요가있는 객체를 제공합니다. 그래서 지금 테스트 중입니다. 그것으로 유인원이 생길지 모르지, 그렇지? – aishpr

+0

예. 문제의 원인입니다. 좋은 사례로서 항상 코드에서 null 체크를 사용하십시오. –

+0

좋아, 내 편집 좀 해봐도 될까요? – aishpr

관련 문제