Я пытаюсь запустить искровое задание в кластере Hadoop, который также отправляет http-запрос на другой сервер. Я использую org.apache.httpcomponents, чтобы сделать этот запрос, который отлично работает локально на моей машине. Однако это не удается в тот момент, когда я отправляю задание в кластер (управляемый Cloudera) со следующей ошибкой:
Исключение класса пользователя: java.lang.NoSuchFieldError: INSTANCE в org.apache.http. conn.ssl.SSLConnectionSocketFactory. (SSLConnectionSocketFactory.java:151) в org.apache.http.impl.client.HttpClientBuilder.build (HttpClientBuilder.java:977) в org.apachetliplientClient.java: 56)
Из всех прочитанных мною ошибок эта ошибка вызвана несколькими версиями JAR-файла Apache Http. Похоже, что движок Hadoop / Spark имеет свою собственную зависимость от клиента Apache Http, и это другая версия, чем та, которую я использую. Поскольку мой jar запускается как часть механизма hadoop / spark, он включает в себя как мою версию http, так и ту, которую требует Hadoop.
Если я добавлю 'compileOnly' для org.apache.httpcomponents в моемbuild.gradle и отправьте, вместо этого я получаю эту ошибку:
Исключительная ситуация класса пользователя: java.lang.NoClassDefFoundError: org / apache / http / impl / client / HttpClients
Есть ли способ для меня настроить это в Gradle, чтобы при сборке JAR он использовал уже существующую версию в Hadoop? то есть. Способ объявления временной зависимости (при локальной загрузке и использовании последней версии, но при сборке UberJar отбросьте зависимость)?
UPDATE Я решил попробовать перейти в другую библиотеку http (okhttp3) чтобы увидеть, решит ли это проблему. Тем не менее, я получаю очень похожее исключение при попытке запуска через кластер и здесь:
Пользовательский класс выдал исключение: java.lang.NoSuchFieldError: Companion на okhttp3.internal.Util. (Util.kt:70) at okhttp3.OkHttpClient. (OkHttpClient.kt: 959)
Похоже, что Cloudera также поставляет версию okhttp со своим клиентом spark2, что является неудачным.