Hadoop Java MapReduce анализирует JSON с проблемами Джексона - PullRequest
2 голосов
/ 15 марта 2012

Я использую анализатор JSON (1.9.5) в программе Hadoop Java M / R (0.20.205). Приведенный ниже пример 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», я получаю только поле идентификатора, а не location.displayName и цену (они не десериализованы и являются нулевыми). Кажется, что аннотация @JsonIgnoreProperties(ignoreUnknown = true) почему-то не работает при работе в MapReduce, и поля, которые я хочу, не десериализуются (все после id равно нулю). Если я добавлю все поля и методы получения и установки к своему Transaction объекту и удалю @JsonIgnoreProperties, то все будет работать нормально. У кого-нибудь есть предположение, почему это происходит? Я просто привел простой пример, но на самом деле мой документ JSON очень сложен, и я не хочу десериализовать все поля из него. Я что-то здесь не так делаю?

Вот как я использую Джексона в основном методе и программе сокращения Java / Map.

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

1 Ответ

4 голосов
/ 16 марта 2012

Это может быть связано с проблемами загрузки класса: старая версия ядра Джексона или около того.Сложность при загрузке классов и аннотаций заключается в том, что VM, по-видимому, разрешено просто отбрасывать аннотации, которые она не распознает.Я не знаю, может ли это быть причиной вашей проблемы, но, возможно, стоит проверить.Hadoop раньше связывал довольно старую версию Jackson (1.1?), И поскольку * 1.4 был добавлен в 1.4, это могло бы объяснить проблему.

Как это могло произойти?Вы должны компилировать, используя более свежую версию (чтобы увидеть аннотацию), но, возможно, среда выполнения использует старую (1.1) версию.Поскольку вы не используете активно класс аннотаций из своего кода (он «только» связан с классом), загрузчик классов затем отбросит эту аннотацию, так как не может найти ее из jar.

...