2016-06-15 4 views
2

Apache Spark를 사용하여 Java 응용 프로그램을 개발 중입니다.httpclient 버전과 Apache Spark 사이의 충돌

<dependency> 
    <groupId>org.apache.httpcomponents</groupId> 
    <artifactId>httpclient</artifactId> 
    <version>4.5.2</version> 
</dependency> 

나는 하나의 JAR 파일로 내 응용 프로그램을 패키지 : 과도 의존성이 내 코드에서

<dependency> 
    <groupId>org.apache.spark</groupId> 
    <artifactId>spark-core_2.10</artifactId> 
    <version>1.2.2</version> 
</dependency> 

:이 버전을 사용하십시오. 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이 같은 아파치 HttpClient를 라이브러리의 이전 버전을로드 한 것을 명확하게 보여주고이 충돌이 이유로 발생합니다.

이 문제를 해결하기위한 좋은 방법은 무엇입니까?

어떤 이유로 Java 코드에서 Spark를 업그레이드 할 수 없습니다. 그러나 EC2 클러스터로 쉽게 할 수있었습니다. 1.6.1 버전보다 높은 버전의 클러스터에 내 Java 코드를 배포 할 수 있습니까?

답변

5

귀하의 게시물에서 말한 것처럼 Spark은 httpclient의 이전 버전을로드하고 있습니다. 해결책은 Maven의 relocation 기능을 사용하여 깔끔한 충돌없는 프로젝트를 만드는 것입니다.

은 여기 pom.xml 파일을 사용하는 방법의 예 :

<project> 
    <!-- Your project definition here, with the groupId, artifactId, and it's dependencies --> 
    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-shade-plugin</artifactId> 
     <version>2.4.3</version> 
     <executions> 
      <execution> 
      <phase>package</phase> 
      <goals> 
       <goal>shade</goal> 
      </goals> 
      <configuration> 
       <relocations> 
       <relocation> 
        <pattern>org.apache.http.client</pattern> 
        <shadedPattern>shaded.org.apache.http.client</shadedPattern> 
       </relocation> 
       </relocations> 
      </configuration> 
      </execution> 
     </executions> 
     </plugin> 
    </plugins> 
    </build> 

</project> 

이 충돌을 해결, org.apache.http.client에서 shaded.org.apache.http.client에 모든 파일을 이동합니다.


원본 게시물 :

<dependency> 
    <groupId>org.apache.spark</groupId> 
    <artifactId>spark-core_2.10</artifactId> 
    <version>1.2.2</version> 
    <scope>provided</scope> 
    <exclusions> 
     <exclusion> 
      <groupId>org.apache.httpcomponents</groupId> 
      <artifactId>httpclient</artifactId> 
     </exclusion> 
    </exclusions> 
</dependency> 

:이 전이 종속성의 문제는 단순히 경우

, 당신은 단지 HttpClient를 스파크에 의해 사용을 배제하기 위해 spark-core 의존성이를 추가 할 수 있습니다 또한 scopeprovided으로 종속성에 추가 했으므로 클러스터에 의해 제공됩니다.

그러나 스파크의 내부 동작으로 인해 주위를 둘러 볼 수 있습니다. 이 작업을 수행 한 후에도 여전히 오류가 발생하면 Maven의 relocation 기능을 사용하여 충돌없는 무료 프로젝트를 만들어 볼 수 있습니다.

Spark의 버전을 업그레이드 할 수 없다는 사실에 대해 정확히 mvnrepository에서 this dependency 선언을 사용 했습니까?

Spark이 하위 버전과 호환되므로 더 높은 버전의 클러스터에 작업을 배포 할 때 문제가 없어야합니다.

+0

문제는 실제로 재배치에 의해 해결되었습니다. 'apache-shade-plugin' 사용법을 자세히 설명해 주시면 답변으로 받아 들일 것입니다. –

+0

@ M-T-A 도움이 되니 기쁩니다. 내 답변을 업데이트했지만 패턴 태그의 올바른 패키지를 참조하고 있음을 확인할 수 있습니까? –

+1

예, 맞습니다. 그냥 대답으로 선택했습니다. –