2012-03-15 92 views
2

我在Hadoop Java M/R程序(0.20.205)中使用Jackson JSON解析器(1.9.5)。下面给出的JSON例子:Hadoop Java MapReduce解析Jackson问题的JSON

{"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 map only作业中解析出数据,我只会得到id字段,而不是location.displayName和价格(它们不是反序列化且为空)。看起来@JsonIgnoreProperties(ignoreUnknown = true)注解在MapReduce中运行时不知何故无法正常工作,并且我想要的字段没有被反序列化(id后的所有内容都为空)。如果我将所有字段,获取者和设置者添加到我的Transaction对象并删除@JsonIgnoreProperties,那么一切正常。 有没有人有建议,为什么发生这种情况?我只是举了一个简单的例子,但实际上我的JSON文档非常复杂,我不想将所有字段反序列化。我在这里做错了什么?

这是我如何在主要方法和Java/Map减少程序中使用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

这可能是由于类加载问题:老版本的杰克逊核心等等。 对于类加载和注释来说,棘手的部分是虚拟机显然允许放弃它无法识别的注释。我不知道这是否会导致问题,但可能值得检查。 Hadoop过去常常捆绑老版本的Jackson(1.1?),并且由于@JsonIgnoreProperties被添加到1.4中,所以这可能解释了这个问题。

这怎么会发生?您必须使用更新版本进行编译(以查看注释),但运行时环境可能使用旧版本(1.1)。因为你没有在你的代码中积极使用注释类(它只“与”类相关联),所以类加载器会放弃这个注释,因为它无法从jar中找到它。

+1

谢谢你!是的,hadoop在classpath上有旧的jakson jar文件。我在我的作业的jar lib目录中包含了更新的版本,但在执行期间没有使用这些版本。 – Marcin 2012-03-19 19:49:06