2014-03-06 2 views
-1

Java 라이브러리 용 jar 파일을 만들려고합니다 (이 mylibrary를 호출 할 수 있음). mylibary에는 maven으로 빌드 된 많은 종속성이 있습니다. 예를 들어, mylibrary가 foo라는 jar에 의존하고 mylibrary가 foo의 버전 1.1을 사용한다고 가정 해보십시오.다른 버전과의 종속성 버전 충돌이없는 jar 파일을 만드는 방법 n

다른 사람들에게이 자바 라이브러리를 공개하고 싶습니다. 그들은 내 라이브러리에 링크하고 그것이 제공하는 API를 사용할 것입니다.

사용자가 자신의 프로젝트를 빌드 (해당 라이브러리를 호출 할 수 있음) 할 때 foo 버전 1.2를 사용한다고 가정하십시오. 따라서 해당 프로젝트에는 두 가지 종속성이 있습니다. mylibrary 1.0 foo 1.2 mylibrary가 foo 1.1을 사용하고 theirlibrary가 foo 1.2를 사용하고 일반적으로 작동하지 않기 때문에 jar 버전 충돌이 발생합니다.

이 문제를 해결하기 위해 maven에서 특수 빌드 타겟을 사용할 수 있습니까? 즉, mylibrary의 모든 내용이 하나의 jar 파일로 묶이고 mylibrary jar 파일 내에 다른 클래스 만로드 할 수 있습니다.

그리고 mylibrary jar에서로드되는 클래스는 mylibrary가 공개하고자하는 API 만 포함하고 종속성은 포함하지 않습니다. 사용자가 foo 1.2를 사용하고 싶다면 자유로이 할 수 있습니다.

기본적으로 mylibrary 1.0은 foo 1.1을 theirlibrary에 강제 적용하지 않습니다. theirlibrary는 foo 1.2를 원할 경우 자유롭게 사용해야합니다.

솔루션으로 ClassLoader를 살펴 봤지만 이것이 효과가 있다고 생각하지 않습니다. 클래스 로더는 클래스의 인스턴스 작성자 만 제어 할 수 있도록하는 것처럼 보입니다. 나는. theirlibrary는 ClassLoader를 사용하여이 문제를 해결할 수 있지만 mylibrary에서 할 수있는 일이 많지 않다고 생각합니다. 나는 그들의 라이브러리에서 클래스 로더를 사용하도록 강요하고 싶지 않다.

자바로 가능합니까? 아니면 자바의 단점입니까?

답변

0

귀하의 질문을 이해 한 경우 귀하의 의존성에 provided 범위를 사용해야합니다. 즉, lib를 사용할 라이브러리/응용 프로그램은 foo 버전을 제공해야합니다.

<dependency> 
    <groupId>...</groupId> 
    <artifactId>foo</artifactId> 
    <!-- this version is applicable only in your project --> 
    <version>1.1</version> 
    <scope>provided</scope> 
</dependency> 

이는 라이브러리를 사용하는 모든 프로젝트가 foo 종속성을 선언해야한다는 것을 의미합니다.

종속성 범위에 대한 자세한 내용은 at the docs을 참조하십시오.

+0

mylibrary의 구현에서 foo 버전을 선택하지 못하게합니까? 나는이 솔루션이 내가 건너 뛰었을 때 상당히 효과적이라고 생각하지 않는다. mylibrary는 theirlibrary가 변경하면 1.1 대신 1.2 버전을 사용하게됩니다. 옳은? 도움을 주셔서 감사합니다. btw – 1337Rooster

+0

테스트를 위해 선택한 버전은 mylibrary의 pom 내에 선언되어 있습니다. 여러 버전을 다시 테스트 해 볼 수 있습니다. 그러나 나는 사용자가 foo 버전을 선택하기를 원하기 때문에 나는 당신의 질문을 이해하지 못한다고 생각한다. 이제는 foo 버전 (나는 혼란 스럽다)을 막을 것을 요구하고있다. –

0

클래스 재배치 기능을 사용하여 Maven shade plugin (http://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html 참고)을 사용할 수 있습니다.

그런 식으로, "foo는"모든 클래스는, 사실, foo는 새로운 개인 인스턴스가 라이브러리에 의해 독점적으로 사용 만들기, (이 경우 myprivate.org.foo에) 다른 패키지로 이전 될 것이다 :

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-shade-plugin</artifactId> 
    <version>2.2</version> 
    <executions> 
     <execution> 
     <phase>package</phase> 
     <goals> 
      <goal>shade</goal> 
     </goals> 
     <configuration> 
      <relocations> 
      <relocation> 
       <pattern>org.foo</pattern> 
       <shadedPattern>myprivate.org.foo</shadedPattern> 
      </relocation> 
      </relocations> 
     </configuration> 
     </execution> 
    </executions> 
    </plugin> 

그러나이 기술을 사용하면 대량으로 폭파 된 병이 생길 수 있습니다. 일반적으로 foo 1.2와 1.1은 라이브러리가 1.2에서 작동 할만큼 충분히 호환되어야합니다. 그럼에도 불구하고 그들의 라이브러리는 1.2를 자유롭게 사용할 수 있습니다. shade plugin의 재배치는 버전 (asm 1.x와 2.x) 사이에 비 호환성이있는 상황에서 목표가됩니다.

음영이 실제로 필요한지 고려하시기 바랍니다.

다른 클래스 로더를 사용하는 대안은 동일한 라이브러리가 다른 버전으로 존재하게하는 OSGI를 사용하는 것입니다.

관련 문제