쉐이딩 종속성 은 종속성 을 포함하고 이름을 변경 하여 (클래스 재배치 및 영향을받는 바이트 코드 및 리소스 다시 쓰기) 자신의 코드와 함께 번들로 제공되는 개인 복사본 을 만드는 과정 입니다.
이 개념은 일반적으로 동네 짱 (일명 뚱뚱한 항아리 )과 관련이 있습니다.
maven shade plugin 때문에이 용어에 대해 약간의 혼동 이 있습니다.이 단일 이름으로 두 가지 작업을 수행합니다 (자신의 페이지 인용).
이 플러그인은 아티팩트를 포함하여 이슈를 jar에 패키지하고 일부 종속성의 패키지 를 음영 처리 ( 즉, 이름 바꾸기) 하는 기능을 제공합니다 .
따라서 음영 부분은 실제로 선택 사항입니다. 플러그인을 사용하면 항아리 (팻 항아리)에 종속성을 포함하고 선택적으로 이름을 변경 (음영) 합니다.
다른 소스 추가 :
라이브러리를 음영 처리하려면 해당 라이브러리의 컨텐츠 파일을 가져 와서 자신의 항아리에 넣고 패키지를 변경하십시오 . 이것은 라이브러리 파일을 다른 패키지로 옮기지 않고 라이브러리 파일을 자신의 jar 파일로 간단히 전달하는 패키징과 다릅니다.
엄밀히 말하면, 종속성 은 흐리게 표시됩니다. 그러나 뚱뚱한 병목이있는 종속성을 "음영 된 병"이라고하는 것이 일반적이며, 해당 병이 다른 시스템의 클라이언트 인 경우 "음영 클라이언트"라고 할 수 있습니다.
귀하의 질문에 링크 한 HBase에 대한 Jira 문제 의 제목 은 다음과 같습니다 .
음영 처리 된 종속성이있는 클라이언트 아티팩트 게시
그래서이 포스트에서 나는 두 개념을 혼동하지 않고 제시하려고합니다.
좋은
Uber jar는 종종 응용 프로그램을 단일 파일로 제공하는 데 사용됩니다 (배포 및 실행이 쉬워집니다). 또한 종속성의 일부 (또는 전부)와 함께 선박 라이브러리에 사용할 수있는 음영 (이러한 라이브러리의 다른 버전을 사용할 수 있습니다) 다른 응용 프로그램에서 사용할 때 충돌을 방지하기 위해.
uber-jar을 빌드하는 방법에는 여러 가지가 있지만 클래스 재배치 기능 maven-shade-plugin
으로 한 단계 더 나아갑니다 .
uber JAR이 다른 프로젝트의 종속성으로 재사용되는 경우 uber JAR에 아티팩트 종속성의 클래스를 직접 포함하면 클래스 경로의 클래스가 중복되어 클래스로드 충돌이 발생할 수 있습니다. 이 문제를 해결하기 위해 음영 처리 된 아티팩트에 포함 된 클래스를 재배치하여 바이트 코드의 개인 복사본을 만들 수 있습니다.
(역사적 주 : Jar Jar Links 는 이전에 재배치 기능을 제공했습니다)
따라서 API에서 해당 라이브러리의 클래스를 공개하지 않는 한 라이브러리 종속성을 구현 세부 사항으로 만들 수 있습니다 .
DecayingSyncQuantanizer
클래스 를 제공 하고 Apache commons-rng에 의존 하는 ACME Quantanizer ™ 프로젝트가 있다고 가정 해 봅시다 ( 물론 , 적절하게 양자화하기 위해서는 XorShift1024Star
.
쉐이드 메이븐 플러그인을 사용하여 uber-jar을 생성하고 내부를 보면 다음 클래스 파일이 표시됩니다.
com/acme/DecayingSyncQuantanizer.class
org/apache/commons/rng/RandomProviderState.class
org/apache/commons/rng/RestorableUniformRandomProvider.class
...
org/apache/commons/rng/core/source64/XorShift1024Star.class
org/apache/commons/rng/core/util/NumberFactory.class
이제 클래스 재배치 기능을 사용하는 경우 :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>org.apache.commons</pattern>
<shadedPattern>com.acme.shaded.apachecommons</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
uber-jar의 내용은 다음과 같습니다.
com/acme/DecayingSyncQuantanizer.class
com/acme/shaded/apachecommons/rng/RandomProviderState.class
com/acme/shaded/apachecommons/rng/RestorableUniformRandomProvider.class
...
com/acme/shaded/apachecommons/rng/core/source64/XorShift1024Star.class
com/acme/shaded/apachecommons/rng/core/util/NumberFactory.class
파일 이름을 바꾸는 것이 아니라 재배치 된 클래스를 참조하는 바이트 코드를 다시 작성합니다 (따라서 내 클래스와 commons-rng 클래스가 모두 변환됩니다).
또한 Shade 플러그인은 dependency-reduced-pom.xml
음영 처리 된 종속성이 <dependencies>
섹션 에서 제거되는 새 POM ( )을 생성합니다 . 이것은 음영 처리 된 jar를 다른 프로젝트의 종속성으로 사용하는 데 도움이됩니다. 따라서 기본 jar 대신 해당 jar을 게시 하거나 둘 다 (음영 된 jar의 한정자를 사용하여) 게시 할 수 있습니다 .
매우 유용 할 수 있습니다 ...
나쁜
... 그러나 그것은 또한 많은 문제를 제기합니다. jar 내에서 모든 종속성을 단일 "네임 스페이스"로 집계하면 지저분해질 수 있으며, 리소스에 대한 음영 및 지저분 함이 필요합니다.
예를 들어 클래스 또는 패키지 이름이 포함 된 리소스 파일을 처리하는 방법은 무엇입니까? 서비스 제공자 디스크립터와 같은 자원 파일은 모두 META-INF/services
?
쉐이드 플러그인은 다음과 같은 리소스 변환기 를 제공 합니다 .
여러 아티팩트의 클래스 / 리소스를 하나의 uber JAR로 집계하는 것은 겹치지 않는 한 간단합니다. 그렇지 않으면 여러 JAR에서 자원을 병합하기위한 일종의 논리가 필요합니다. 여기에서 자원 변압기가 시작됩니다.
그러나 여전히 혼란스럽고 문제를 예측하기가 거의 불가능합니다 (생산 과정에서 어려운 문제를 종종 발견합니다). 왜 우리가 멈춘 건물 지방 병을 참조하십시오 .
대체로 뚱뚱한 항아리를 독립 실행 형 앱 / 서비스로 배포하는 것은 여전히 매우 보편적이며 문제를 알고 있어야하며 일부는 음영 이나 다른 트릭 이 필요할 수 있습니다 .
못난이
더 어려운 문제 (디버깅, 테스트 가능성, OSGi 및 이국적인 클래스 로더와의 호환성 ...)가 많이 있습니다.
그러나 더 중요한 것은 라이브러리를 만들 때 독립형 앱 / 서비스로 배포하는 뚱뚱한 항아리와는 달리 항아리가 여러 가지 상황에서 사용될 수 있기 때문에 제어 할 수 있다고 생각한 다양한 문제가 점점 더 복잡해지고 있습니다. 통제 된 환경에서).
예를 들어, ElasticSearch는 배송 된 병의 일부 종속성을 음영 처리하는 데 사용했지만 이를 중지하기로 결정했습니다 .
버전 2.0 이전에는 Elasticsearch가 동일한 아티팩트 내에 음영 처리되고 패키지 된 일부 (전부는 아님) 공통 종속성이있는 JAR로 제공되었습니다. 이를 통해 자체 애플리케이션에 Elasticsearch를 내장 한 Java 사용자는 Guava, Joda, Jackson 등과 같은 모듈의 버전 충돌을 피할 수있었습니다. 물론 여전히 충돌을 일으킬 수있는 Lucene과 같은 음영 처리되지 않은 종속성 목록이 여전히있었습니다.
불행히도, 음영은 복잡하고 오류가 발생하기 쉬운 프로세스로 일부 사람들의 문제는 해결하고 다른 사람들에게는 문제가 발생합니다. 음영 처리를하면 빌드 중에 패키지 이름이 바뀌기 때문에 개발자와 플러그인 작성자가 코드를 올바르게 작성하고 디버그하기가 매우 어렵습니다. 마지막으로, 우리는 음영 처리되지 않은 Elasticsearch를 테스트 한 다음 음영 처리 된 병을 배송했으며 테스트하지 않은 것은 배송하지 않습니다.
2.0 이후부터 쉐이딩하지 않고 Elasticsearch를 제공하기로 결정했습니다.
그것들은 음영 처리 된 항아리가 아닌 음영 처리 된 종속성을 나타냅니다.