maven-shade-plugin의 용도와 Java 패키지를 재배치하는 이유는 무엇입니까?
maven-shade-plugin이 누군가의 pom.xml에 사용되고 있는 것을 발견했습니다.저는 maven-shade-plugin을 사용해 본 적이 없기 때문에(Maven n00b입니다), 이것을 사용하는 이유와 기능을 이해하려고 했습니다.
Maven 문서를 봤는데 이 문장이 이해가 안 돼요.
이 플러그인은 종속성을 포함하여 uber-jar에 아티팩트를 패키징하고 일부 종속성의 패키지를 음영(예: 이름 변경)할 수 있는 기능을 제공합니다.
페이지에 있는 서류는 그다지 새로울 것 같지 않다.
우버 항아리가 뭐죠?왜 누군가 그걸 만들고 싶어 했을까요?종속성 패키지의 이름을 바꾸면 무슨 소용입니까?maven-shade-plugin apache 페이지에서 "Uber Jar용 콘텐츠 선택" 등의 예를 살펴보려고 했지만, "shading"으로 무엇을 하고 있는지 아직도 이해할 수 없습니다.
예시/용례에 대한 힌트(이 경우 음영이 필요한 이유 설명 - 해결 중인 문제 설명)가 있으면 감사하겠습니다.마지막으로 메이븐 셰이드 플러그인은 언제 사용해야 하나요?
Uber JAR은 한마디로 모든 것을 포함하는 JAR입니다.
보통 메이븐에서는 의존관리가 중요합니다.아티팩트는 자신의 클래스/리소스만 포함합니다.Maven은 프로젝트 구축 시기에 따라 프로젝트의 모든 아티팩트(JAR 등)를 찾아냅니다.
uber-jar는 모든 종속성을 취하여 종속성의 내용을 추출하여 프로젝트 자체의 클래스/리소스와 함께 하나의 큰 JAR에 넣는 것입니다.이러한 uber-jar를 갖추면 앱을 실행하기 위한 작은 JAR이 아닌 하나의 큰 JAR만 필요하기 때문에 실행이 용이합니다.또, 경우에 따라서는 배포도 용이하게 됩니다.
참고로, maven 의존관계로서 uber-jar를 사용하는 것은 피하고, maven 의존관계 해결기능을 망치고 있다.일반적으로 실제 배포 또는 수동 배포를 위한 최종 아티팩트에 대해서만 uber-jar를 만들지만 Maven 저장소에 배치하기 위한 것은 아닙니다.
업데이트: "의존관계 패키지의 이름을 바꾸면 무슨 의미가 있습니까?"라는 질문의 일부에 답변하지 않은 것을 알게 되었습니다.다음은 유사한 질문을 하는 사람들에게 도움이 될 수 있는 몇 가지 간단한 업데이트입니다.
도입을 용이하게 하기 위해 uber-jar를 작성하는 것도 셰이드 플러그인의 사용 사례 중 하나입니다.패키지 이름을 변경하는 일반적인 사용 사례도 있습니다.
예를 들어, 저는 지금Foo
라이브러리는 특정 버전(예: 1.0)에 따라 달라집니다.Bar
도서관.의 다른 버전을 사용할 수 없는 경우Bar
lib (API 변경이나 기타 기술적인 문제 등)내가 간단히 선언한다면Bar:1.0
~하듯이Foo
의 Maven 의존도가 문제가 될 수 있습니다.aQux
프로젝트는 에 의존하고 있다Foo
, 및 기타Bar:2.0
(사용할 수 없습니다).Bar:1.0
왜냐면Qux
에서 새로운 기능을 사용할 필요가 있다Bar:2.0
딜레마는 다음과 같습니다.Qux
사용하다Bar:1.0
(어느쪽인가)Qux
코드가 기능하지 않습니다) 또는Bar:2.0
(어느쪽인가)Foo
의 코드가 기능하지 않는 경우)
이 문제를 해결하기 위해 개발자는Foo
음영 플러그인을 사용하여 용도의 이름을 변경할 수 있습니다.Bar
의 모든 클래스가Bar:1.0
항아리가 박혀 있다Foo
jar 및 임베디드 기기 패키지Bar
클래스가 에서 변경되었습니다.com.bar
로.com.foo.bar
그렇게 함으로써Qux
안심하고 의존할 수 있다Bar:2.0
왜냐하면 지금Foo
더 이상 의존하지 않는다Bar
또, 독자적인 카피를 사용하고 있습니다.Bar
다른 패키지에 있습니다.
저는 최근에 왜 탄력적 검색의 의존성을 일부(전부는 아니지만)를 음영화하고 재배치하는지 궁금했습니다.다음은 프로젝트 관리자인 @kimchy의 설명입니다.
음영 부분은 의도적인 것이고, 우리가 탄성 검색에 사용하는 음영 라이브러리는 탄성 검색의 모든 목적과 목적을 위한 것입니다.사용되는 버전은 라이브러리의 내부 기능(및 버전 간의 변경)에 기초한 라이브러리의 사용 방법과 밀접하게 관련되어 있습니다.
그나저나, 저는 실제로 여러 개의 탄성 검색을 제공하는데 문제가 없습니다. 하나는 루센이 음영 처리되지 않은 병이고, 다른 하나는 루센이 음영 처리되어 있습니다.메이븐으로 어떻게 하는지 잘 모르겠어요.예를 들어 netty/jackson을 음영 처리하지 않는 버전은 제공하고 싶지 않습니다.이는 예를 들어 netty의 깊은 사용 탄력성 검색이 가지고 있기 때문입니다(예를 들어, 현재 버전을 제외한 이전 버전의 모든 netty에서 향후 버퍼링 개선 기능을 사용하면 실제로 훨씬 적은 양의 메모리를 사용할 수 있기 때문입니다).
-- https://github.com/elasticsearch/elasticsearch/issues/2091#issuecomment-7156766
그리고 드류르의 또 다른 이야기:
shading은 의존관계(특히 netty, lucene, guava)를 코드에 가깝게 유지하여 업스트림프로바이더가 지연되어도 문제를 해결할 수 있도록 하기 위해 중요합니다.특정 문제(#2091 등)에 도움이 되는 모듈화된 버전의 코드를 배포할 수도 있지만, 현시점에서는 단순히 음영화된 종속성을 제거할 수는 없습니다.더 나은 솔루션이 나올 때까지 목적에 맞게 로컬 버전의 ES를 구축할 수 있습니다.
-- https://github.com/elasticsearch/elasticsearch/pull/3244#issuecomment-20125452
이것이 하나의 사용 사례입니다.예를 들어 다음과 같이 maven-shade-plugin을 Elastic Search의 pom.xml(v0.90.5)에서 사용하는 방법을 나타냅니다.그artifactSet::include
행은 uber JAR에 어떤 종속성을 끌어당길지 지시합니다(기본적으로 압축 해제 후 타겟 탄성 검색 항아리가 생성되면 Elastic Search의 자체 클래스와 함께 재패키지됩니다).(JAR 파일은 프로그램의 클래스, 리소스 등, 메타데이터를 포함한 ZIP 파일입니다).1개를 추출하여 조립 방법을 확인할 수 있습니다.)
그relocations::relocation
각 경우 종속성 클래스에 지정된 대체를 적용한다는 점을 제외하면 행은 유사하다.- 이 경우, 종속성 클래스는 다음과 같다.org.elasticsearch.common
.
마지막으로 그filters
이 섹션은 JAR 메타데이터, 개미 빌드 파일, 텍스트 파일 등 일부 종속성이 패키지화되어 있지만 Uber JAR에 속하지 않는 대상 JAR에서 제외됩니다.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<minimizeJar>true</minimizeJar>
<artifactSet>
<includes>
<include>com.google.guava:guava</include>
<include>net.sf.trove4j:trove4j</include>
<include>org.mvel:mvel2</include>
<include>com.fasterxml.jackson.core:jackson-core</include>
<include>com.fasterxml.jackson.dataformat:jackson-dataformat-smile</include>
<include>com.fasterxml.jackson.dataformat:jackson-dataformat-yaml</include>
<include>joda-time:joda-time</include>
<include>io.netty:netty</include>
<include>com.ning:compress-lzf</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>org.elasticsearch.common</shadedPattern>
</relocation>
<relocation>
<pattern>gnu.trove</pattern>
<shadedPattern>org.elasticsearch.common.trove</shadedPattern>
</relocation>
<relocation>
<pattern>jsr166y</pattern>
<shadedPattern>org.elasticsearch.common.util.concurrent.jsr166y</shadedPattern>
</relocation>
<relocation>
<pattern>jsr166e</pattern>
<shadedPattern>org.elasticsearch.common.util.concurrent.jsr166e</shadedPattern>
</relocation>
<relocation>
<pattern>org.mvel2</pattern>
<shadedPattern>org.elasticsearch.common.mvel2</shadedPattern>
</relocation>
<relocation>
<pattern>com.fasterxml.jackson</pattern>
<shadedPattern>org.elasticsearch.common.jackson</shadedPattern>
</relocation>
<relocation>
<pattern>org.joda</pattern>
<shadedPattern>org.elasticsearch.common.joda</shadedPattern>
</relocation>
<relocation>
<pattern>org.jboss.netty</pattern>
<shadedPattern>org.elasticsearch.common.netty</shadedPattern>
</relocation>
<relocation>
<pattern>com.ning.compress</pattern>
<shadedPattern>org.elasticsearch.common.compress</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/license/**</exclude>
<exclude>META-INF/*</exclude>
<exclude>META-INF/maven/**</exclude>
<exclude>LICENSE</exclude>
<exclude>NOTICE</exclude>
<exclude>/*.txt</exclude>
<exclude>build.properties</exclude>
</excludes>
</filter>
</filters>
</configuration>
</plugin>
</plugins>
음영 처리된 자리의 필요성의 한 예가 AWS Lambda 함수라고 생각합니다.일반적인 .war 파일에서 볼 수 있는 전체 .jars 컬렉션이 아닌 하나의 jar만 업로드할 수 있는 것 같습니다.따라서 프로젝트의 모든 종속성을 포함하는 단일 .jar를 생성하면 이 작업을 수행할 수 있습니다.
작은 경고
maven-shade-plugin을 사용하고 싶은 이유는 기재되어 있지 않지만 (선택한 답변이 잘 되어있기 때문에) 문제가 있었던 것 같습니다.JAR가 변경되어(그 이후), 소프트웨어에 퇴행의 원인이 되었습니다.
그래서 이것(또는 maven-jar-plugin)을 사용하는 대신 문제없이 작동하는 JarJar의 바이너리를 사용했습니다.
적절한 해결책을 찾는데 시간이 걸려서 여기에 제 해결책을 올렸습니다.
Downlaod JarJar의 JAR 파일
이 항아리는 여기서 다운로드 할 수 있습니다.https://code.google.com/p/jarjar/ 왼쪽 메뉴에는 다운로드할 수 있는 링크가 있습니다.
JarJar를 사용하여 패키지 간에 JAR 클래스를 재배치하는 방법
이 예에서는 패키지를 "com.snarxml.snar"에서 "io.kuku.dependencies.com.snarxml.snar"로 변경합니다.- 소스 JAR의 이름은 "snar-snarsind-2.6.4.jar"이고 변경된 새로운 (타겟) JAR의 이름은 "ku-snar-sn-snars-ind-2.6.4.jar"입니다.jar 파일입니다.
규칙을 만듭니다.txt" 파일입니다.파일의 내용은 ('@' 문자 앞의 마침표 참조): rule com.fasterxml.jackson이어야 합니다.** io.kuku.dependencies.com.http xml.http://field@1
java -jar jarjar-1.4.jar process rules 명령을 실행합니다.txt jackson-backsind-2.6.4.jar kuku-backs-backsind-2.6.4.jar
로컬 저장소에 수정된 JAR 설치
이 경우 "c:\my-jars" 폴더에 3개의 파일을 설치합니다.
mvn install:install-file=C:\my-jars\ku-jackson-annotations-2.6.4.jar -DgroupId=io.kuku.dependencies -DartifactId=ku-jackson-annotations -Dvers=2.6.4 -Dpackaging=jar.dependencencies -dents -dents -DgroupIdupactIdupactIdents -DgroupIdents -DgroupIdupactions -dent
mvn 설치:install-file=C:\my-jars\ku-jackson-core-2.6.4.jar -DgroupId=io.kuku.dependencies -DartifactId=ku-jackson-core -Dversion=2.6.4 -Dpackaging=jar
mvn install:install-file=C:\my-jars\ku-jackson-databind-2.6.4.jar -DgroupId=io.kuku.dependencies -DartifactId=ku-jackson-annations -Dversion=2.6.4 -Dpackaging=jar.dependencies -dependencies -ditions -DgroupIdupactIdupactions -DgroupIdents -DgroupId -DgroupIdents -
프로젝트 폼에서 수정된 JAR 사용
이 예에서는 프로젝트 pom의 "의존성" 요소를 다음과 같이 나타냅니다.
<dependencies>
<!-- ================================================== -->
<!-- kuku JARs -->
<!-- ================================================== -->
<dependency>
<groupId>io.kuku.dependencies</groupId>
<artifactId>kuku-jackson-annotations</artifactId>
<version>2.6.4</version>
</dependency>
<dependency>
<groupId>io.kuku.dependencies</groupId>
<artifactId>kuku-jackson-core</artifactId>
<version>2.6.4</version>
</dependency>
<dependency>
<groupId>io.kuku.dependencies</groupId>
<artifactId>kuku-jackson-databind</artifactId>
<version>2.6.4</version>
</dependency>
</dependencies>
언급URL : https://stackoverflow.com/questions/13620281/what-is-the-maven-shade-plugin-used-for-and-why-would-you-want-to-relocate-java
'programing' 카테고리의 다른 글
브라우저의 소실 요소를 검사하려면 어떻게 해야 합니까? (0) | 2022.12.21 |
---|---|
PHP 랜덤 문자열 생성기 (0) | 2022.12.21 |
SQL에서 지정된 양을 초과하는 첫 번째 행을 가져오는 방법 (0) | 2022.12.21 |
서브쿼리가 NULL인지 확인합니다. (0) | 2022.12.21 |
MySQL에 있는 경우 업데이트하고 없는 경우 삽입(AKA "upsert" 또는 "Merge")하려면 어떻게 해야 합니까? (0) | 2022.12.21 |