2012-03-15 4 views
2

Hadoop Java M/R 프로그램 (0.20.205)에서 Jackson JSON 구문 분석기 (1.9.5)를 사용하고 있습니다. 아래의 JSON 예제 감안할 때 :Hadoop Java MapReduce JSON with Jackson 문제 구문

이제
{"id":23423423, "name":"abc", "location":{"displayName":"Florida, Rosario","objectType":"place"}, "price":1234.55} 

, 난 그냥 아이디, location.displayName을 구문 분석하고 싶은 말은, 가격은 그래서 나는 다음과 같은 자바 객체를 만들어 보자 내가 원치 않는 필드를 생략하고있다.

@JsonIgnoreProperties(ignoreUnknown = true) 
public class Transaction { 
    private long id; 
    private Location location; 
    private double price; 

    private static final ObjectMapper mapper = new ObjectMapper(); 

    ..setter/getter method would be here for id, Location, price 

    @JsonIgnoreProperties(ignoreUnknown = true) 
    public static class Location { 
    private String displayName; 

    public String getDisplayName { return displayName; } 
    public void setDisplayName(String displayName) { this.displayName = displayName; } 
    } 

    public static final Transaction fromJsonDoc(String jsonDoc) throws IOException { 
    JsonNode rootNode = mapper.readTree(jsonDoc); 
    return mapper.treeToValue(rootNode, Transaction.class); 
    } 
} 

독립 실행 형 모드 (Hadoop 분산 모드 아님)로이 프로그램을 실행할 때. 내가 원하는 모든 필드가 올바르게 구문 분석됩니다. 그러나 Hadoop지도 작업에서 데이터를 구문 분석하는 즉시 id 필드 만 가져오고 location.displayName 및 가격은 반환하지 않습니다 (이들은 deserialize되지 않고 null입니다). @JsonIgnoreProperties(ignoreUnknown = true) 어노테이션은 MapReduce에서 실행될 때 어떻게 든 작동하지 않는 것으로 보이고 원하는 필드는 deserialize되지 않습니다 (id 이후의 모든 항목은 null). 모든 필드와 getter 및 setter를 Transaction 개체에 추가하고 @JsonIgnoreProperties을 제거하면 모든 것이 잘 동작합니다. 누구에게 이런 일이 발생했는지 제안이 있습니까? 방금 예제를 들었지만 실제로는 JSON 문서가 매우 복잡하고 모든 필드를 비 직렬화하고 싶지 않습니다. 내가 여기서 뭔가 잘못하고있는거야?

이 방법은 Jackson을 main 메소드 및 Java/Map reduce 프로그램에서 사용하는 방법입니다.

Transaction tran = Transaction.fromJsonDoc(jsonRec); 
System.out.println("id: " + tran.getId()); //works in both 
System.out.println("location: " + tran.getLocation().getDisplayName()); //works only in standalone execution but not in Map/Reduce 

답변

4

이것은 클래스로드 문제로 인한 것일 수 있습니다. 예전 버전의 jackson 코어 정도입니다. 클래스 로딩과 주석을 다루는 까다로운 부분은 VM이 인식 할 수없는 주석을 삭제할 수 있다는 것입니다. 이것이 문제의 원인이 될 수 있는지는 모르겠지만 점검할만한 가치가있을 수 있습니다. Hadoop은 다소 오래된 버전의 Jackson (1.1?)을 번들로 사용했고, @JsonIgnoreProperties이 1.4에 추가 되었기 때문에 문제를 설명 할 수 있습니다.

어떻게 이런 일이 발생할 수 있습니까? 보다 최신 버전을 사용하여 컴파일해야합니다 (주석을 보려면).하지만 런타임 환경에서 이전 버전 (1.1)을 사용하고있을 수 있습니다. 코드에서 주석 클래스를 적극적으로 사용하지 않으므로 (클래스와 연관된 "유일한") 클래스 로더는이 주석을 병에서 찾을 수 없으므로이 주석을 삭제합니다.

+1

고마워요! 그래, 그 경우에, hadoop은 classpath에 오래된 jakson jar 파일을 가지고있다. 내 직업의 jar lib 디렉토리에 최신 버전이 포함되어 있지만 실행 중에는 사용되지 않았습니다. – Marcin