httpclient版本与Apache Spark之间的java冲突
我正在使用ApacheSpark开发一个Java应用程序。我使用这个版本:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.10</artifactId>
<version>1.2.2</version>
</dependency>
在我的代码中,有一个过渡依赖项:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
我将应用程序打包到一个JAR文件中。当使用spark-submit
在EC2实例上部署它时,我得到了这个错误
Caused by: java.lang.NoSuchFieldError: INSTANCE
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<clinit>(SSLConnectionSocketFactory.java:144)
at com.amazonaws.http.apache.client.impl.ApacheConnectionManagerFactory.getPreferredSocketFactory(ApacheConnectionManagerFactory.java:87)
at com.amazonaws.http.apache.client.impl.ApacheConnectionManagerFactory.create(ApacheConnectionManagerFactory.java:65)
at com.amazonaws.http.apache.client.impl.ApacheConnectionManagerFactory.create(ApacheConnectionManagerFactory.java:58)
at com.amazonaws.http.apache.client.impl.ApacheHttpClientFactory.create(ApacheHttpClientFactory.java:50)
at com.amazonaws.http.apache.client.impl.ApacheHttpClientFactory.create(ApacheHttpClientFactory.java:38)
此错误清楚地表明SparkSubmit
已加载同一Apache httpclient库的较旧版本,因此发生此冲突
解决这个问题的好办法是什么
由于某些原因,我无法在Java代码上升级Spark。然而,我可以用EC2集群轻松做到这一点。是否可以在更高版本(如1.6.1版本)的集群上部署java代码
# 1 楼答案
正如您在帖子中所说,Spark正在加载} 工具生成一个整洁的无冲突项目
httpclient
的旧版本。解决方案是使用Maven的^{下面是一个如何在
pom.xml
文件中使用它的示例:这将把所有文件从
org.apache.http.client
移动到shaded.org.apache.http.client
,从而解决冲突原创帖子:
如果这只是一个可传递依赖项的问题,您可以将其添加到
spark-core
依赖项中,以排除Spark使用的HttpClient:我还在依赖项中添加了
scope
作为provided
,因为它将由集群提供然而,这可能会影响Spark的内部行为。如果执行此操作后仍然出现错误,可以尝试使用Maven的^{} 工具,该工具将生成一个整洁的无冲突项目
关于不能升级Spark的版本这一事实,您是否使用了来自mvnrepository的this dependency声明
Spark向后兼容,在更高版本的集群上部署作业应该不会有任何问题