java.lang.NoSuchFieldError: INSTANCE in HttpClient when running Oozie

java.lang.NoSuchFieldError: INSTANCE in HttpClient when running Oozie

我有一个 Java 应用程序(作为 Maven 项目),它使用 HttpClient (v 4.5) 访问 REST API,然后将 GET 响应写入 HDFS 作为 JSON. 这在 Eclipse IDE 中工作正常。这是我的依赖项:

<dependencies>
  <dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5</version>
  </dependency>
  <dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.3.1</version>
  </dependency>
  <dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>2.2.0</version>
</dependency>

当我尝试将它与 Oozie 集成时,因为我计划定期进行 REST API 调用和 HDFS 写入,我遇到:

Caused by: java.lang.NoSuchFieldError: INSTANCE
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<clinit>(SSLConnectionSocketFactory.java:144)
at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:955)
at com.accenture.pdc.digital.sf.datascience.RestController.<init> RestController.java:26)
at com.accenture.pdc.digital.sf.datascience.App.main(App.java:53)

(RestController.java 和 App.java 是我的 类)。 当我跟踪时,问题出在我代码的这一行:

CloseableHttpClient httpClient = HttpClients.createDefault();

在库源代码中进一步探索,有这个被弃用:

AllowAllHostnameVerifier.INSTANCE

当我搜索同样的问题时,有人说这可能是HttpClient 或HttpCore 的多版本冲突。所以可能的罪魁祸首可能是 hadoop-client 的 HttpClient 依赖项(只是我的直觉)。如何判断是否是多版本冲突?如果是,我该如何解决?

如果没有,是否有打开 HttpClient 的替代解决方案来避免此问题?我应该使用 HttpClient 以外的库吗?

对我有用的第一个替代方法是使用 Jersey 而不是 HttpClient。由于 hadoop-client 已经使用 jersey-core 和 jersey-client 作为依赖项,所以不妨使用已经存在的东西。另外,我把hadoop-client升级到了2.6.0,因为我的Hadoop版本是2.6.0.

然后,当我删除 pom.xml 中的 http-client 时,我注意到突然出现了 4.2.5 版的 http-client。它证实 hadoop-client 也有它作为依赖项,正如我之前怀疑的那样。所以当我恢复到 HttpClient 解决方案并调整一些行以适应旧版本时,它在 Oozie 中成功运行。