2012-03-15 17 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} 

、私はちょうど、IDを解析したいlocation.displayName、および価格はので、私は、次のJavaオブジェクトを作成し、私は不要なフィールドを省略していましょう。

@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と価格ではなく、デシリアライズされずnullになります。 @JsonIgnoreProperties(ignoreUnknown = true)注釈は、MapReduceで実行しているときに、何らかの形で機能していないと思われます。また、必要なフィールドは逆シリアル化されません(idの後のすべてがnullです)。すべてのフィールドとgetterとsetterをTransactionオブジェクトに追加して@JsonIgnorePropertiesを削除すると、すべて正常に動作します。 これはなぜ起こっているのですか?私は単純な例を挙げましたが、実際にはJSONのドキュメントは非常に複雑で、すべてのフィールドを逆シリアル化したくありません。私はここで何か間違っていますか?

これは、メインメソッドとJava/Map reduceプログラムでJacksonを使用する方法です。

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 coreほどです。 クラスロードと注釈の面倒な部分は、VMが認識できない注釈を削除するだけであることが明らかです。これがあなたの問題を引き起こすかどうかは分かりませんが、チェックする価値はあります。 Hadoopはかなり古いバージョンのJackson(1.1?)をバンドルしていましたが、@JsonIgnorePropertiesが1.4に追加されているので、これは問題を説明するかもしれません。

これはどのように発生する可能性がありますか?より最新のバージョン(注釈を見るために)を使ってコンパイルする必要がありますが、ランタイム環境では古いバージョン(1.1)を使用している可能性があります。コードからアノテーションクラスを積極的に使用しないため(クラスに関連付けられた「唯一の」)、クラスローダは、このアノテーションをjarファイルから見つけることができないため、アノテーションを削除します。

+1

ありがとうございます!うん、その場合、hadoopはクラスパス上に古いjakson jarファイルを持っています。私は仕事のjar libディレクトリに新しいバージョンを入れましたが、それらは実行中に使われませんでした。 – Marcin