Конфликтующие .банки в моей толстой банке против Hadoop

#java #maven #hadoop

#java #maven #hadoop

Вопрос:

Я бы хотел использовать возможности json-io 4.10.1. К сожалению, моя версия hadoop (2.8.4) включает версию 2.5.1. Когда мое приложение запускается, оно извлекает json-io из /usr/lib/hadoop-yarn-lib вместо классов, включенных в мой application .jar.

Например, в этой более новой версии нет метода JsonReader.jsonToJava со вторым аргументом, который принимает параметры, и эта версия лучше справляется с отображением моих объектов в / из json.

При выполнении приложения я получаю сообщение об ошибке, что не удалось найти подходящий метод. В конечном итоге в качестве временной меры я удалил файл /usr/lib/hadoop-yarn-lib/json-io-2.5.1.jar и приложение нашло «локальную» версию и успешно запустилось.

Так что в моем pom.xml , я объявляю json-io как зависимость:

 <dependency>
  <groupId>com.cedarsoftware</groupId>
  <artifactId>json-io</artifactId>
  <version>4.10.1</version>
</dependency>
 

И я настроил плагин shade для создания fat .jar. Результирующий jar содержит JsonReader.class из правильной версии json-io.

Этот старый jar находится непосредственно в пути к классу hadoop (/usr/lib/hadoop-yarn-lib/*).

Я ожидаю, что загрузчик классов найдет связанное JsonReader.class , но это вытягивает один из classpath.

Комментарии:

1. Лучшее, что я могу сказать, исходя из моего довольно плохого понимания предмета, это то, что json-io уже загружен где-то на этом пути, и загрузчик классов не будет повторно загружать его для меня.

2. Кажется, это связано с этим вопросом , который в конечном итоге привел к исправлению MAPREDUCE-1700 , которое позволяет устанавливать загрузчик классов для приложения в версии 2.9 . Не совсем полезно для меня, застрявшего в 2.8.4

3. почему бы вам не добавить комплектную версию (которую вы не используете) для исключения зависимостей hadoop-yarn в вашем pom-файле?

4. @epcpu, я не уверен, что понимаю, что ты имеешь в виду. Программа запуска yarn загружает json-io перед тем, как перейти к моему приложению.

Ответ №1:

В Maven вы можете исключить более глубокие зависимости:

 <dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-yarn</artifactId>
  <version>3.2.0</version>
  <exclusions>
    <exclusion>
      <groupId>com.cedarsoftware</groupId>
      <artifactId>json-io</artifactId>
    </exclusion>
  </exclusions>
</dependency>
 

Это должно предотвратить извлечение другой json-io библиотеки.

Комментарии:

1. Спасибо за этот ответ, @Sascha, но я думаю, что, возможно, я был неясен. Происходит обратное . Я правильно включаю новый json-io в maven и связываю его с shade. В загрузчике yarn (который запускает приложение mapreduce) уже есть JsonReader (например), загруженный из более старой версии json-io, потому что это то, что он использует. В принципе, мне нужно перезагрузить уже загруженный класс (я думаю).

2. Тогда вам придется искать уникальный класс (например, SpecialClass), который находится в jar, который также содержит желаемую версию JsonReader, но не в другом jar. Затем вы могли бы загрузить класс через SpecialClass.class.getClassLoader().loadClass("my.json.JSonReader");