Для чего используется Maven-shade-plugin и почему вы хотите переместить пакеты Java?
Я нашел Maven-shade-плагин, используемый в чьем-то pom.XML. Я никогда не использовал Maven-shade-plugin раньше (и я Maven n00b), поэтому я попытался понять причину использования этого и что он делает.
Я посмотрел на Maven docs, но я не могу понять это утверждение:
"этот плагин предоставляет возможность упаковать артефакт в uber-jar, включая его зависимости и затенить - т. е. переименовать-пакеты некоторых из зависимостей."Документация на странице не кажется очень дружелюбной для новичков.
Что такое " Uber jar?- Зачем кому-то понадобилось его делать? Какой смысл переименовывать пакеты зависимостей? Я попытался пройти примеры на странице apache Maven-shade-plugin, такие как" выбор содержимого для Uber Jar", но я все еще не могу понять, что происходит с "затенением"."
любые указатели на иллюстративные примеры / варианты использования (с объяснение того, почему затенение было необходимо в этом случае - какая проблема это решение) было бы оценено. Наконец, когда я должен использовать Maven-shade-plugin?
3 ответов
Uber JAR, короче говоря, это Банка, содержащая все.
обычно в Maven мы полагаемся на управление зависимостями. Артефакт содержит только классы/ресурсы самого себя. Maven будет нести ответственность, чтобы найти все артефакты (банки и т. д.), что проект в зависимости от того, когда проект будет построен.
uber-jar-это то, что принимает все зависимости и извлекает содержимое зависимостей и помещает их в классы / ресурсы самого проекта, в одна большая банка. Имея такой uber-jar, его легко выполнить, потому что вам понадобится только одна большая банка вместо тонны маленьких банок для запуска вашего приложения. В некоторых случаях это также облегчает распределение.
просто Примечание. Избегайте использования uber-jar в качестве зависимости Maven, так как это разрушает функцию разрешения зависимостей Maven. Обычно мы создаем uber-jar только для конечного артефакта для фактического развертывания или для ручного распространения, но не для сдачи Maven хранилище.
Update: я только что обнаружил, что не ответил на одну часть вопроса: "Какой смысл переименовывать пакеты зависимостей?". Вот некоторые краткие обновления и, надеюсь, помогут людям, имеющим аналогичный вопрос.
создание uber-jar для простоты развертывания является одним из вариантов использования Shade plugin. Существуют также другие распространенные случаи использования, которые включают переименование пакетов.
например, я разрабатываю Foo
библиотека, что зависит от конкретной версии (например, 1.0)Bar
библиотека. Предполагая, что я не могу использовать другую версию Bar
lib (потому что изменение API или другие технические проблемы и т. д.). Если я просто объявлю Bar:1.0
as Foo
зависимость в Maven, можно попасть в проблему: a Qux
проект зависит от Foo
, а также Bar:2.0
(и он не может использовать Bar:1.0
, потому что Qux
нужно использовать новую функцию в Bar:2.0
). Вот дилемма: должен Qux
использовать Bar:1.0
(который Qux
код не будет работать) или Bar:2.0
(где Foo
код не будет работать)?
чтобы решить эту проблему, разработчик Foo
можно использовать Shade plugin для переименования его использования Bar
, Так что все классы в Bar:1.0
jar встроены в Foo
jar и пакет встроенного Bar
классы изменены с com.bar
to com.foo.bar
. Поступая так,Qux
может безопасно зависит от Bar:2.0
потому что теперь Foo
больше не зависит от Bar
, и это использование собственной копии "изменено"Bar
находится в другом пакете.
недавно мне было интересно, почему Elasticsearch оттеняет и перемещает несколько (но не все) его зависимостей. Вот объяснение от сопровождающего проекта,@kimchy:
часть затенения преднамеренна, затененные библиотеки, которые мы используем в elasticsearch, для всех намерений и целей являются частью elasticsearch, используемая версия тесно связана с тем, что Elasticsearch предоставляет и как он использует библиотеку на основе внутренних как работает библиотека (и что изменения между версиями), Нетти и гуава являются отличными примерами.
кстати, у меня нет проблем с предоставлением нескольких банок elasticsearch, один с lucene не затенен, а один с Lucene затенен. Не уверен,как это сделать с maven. Я не хочу предоставлять версию, которая не затеняет netty/jackson, например, из-за глубокого интимного использования elasticsearch (например, использование предстоящего улучшения буферизации с любая предыдущая версия netty, кроме текущей, фактически будет использовать больше памяти по сравнению с использованием значительно меньше).
-- https://github.com/elasticsearch/elasticsearch/issues/2091#issuecomment-7156766
и еще здесь от drewr:
затенение важно, чтобы наши зависимости (в частности, netty, lucene, guava) были близки к нашему коду, чтобы мы могли исправить проблему, даже если вышестоящий поставщик отстает. Возможно, мы будем распространять модульные версии кода, которые помогут с вашей конкретной проблемой (например, #2091), но мы не можем просто удалить затененные зависимости в это время. Вы можете создать локальную версию ES для своих целей, пока не будет лучшего решения.
-- https://github.com/elasticsearch/elasticsearch/pull/3244#issuecomment-20125452
Итак, это один вариант использования. Что касается иллюстративного примера, ниже показано, как Maven-shade-plugin используется в POM elasticsearch.XML (с версии v0.90.5). The artifactSet::include
линии инструктируют его, какие зависимости тянуть в Uber JAR (в основном, они распаковываются и повторно упаковываются вместе с собственными классами elasticsearch, когда создается целевой Elasticsearch jar. (Если вы еще не знали об этом, файл JAR-это просто ZIP-файл, содержащий классы, ресурсы и т. д. и некоторые метаданные. Вы можете извлечь один, чтобы увидеть как это сложить.)
на relocations::relocation
строки похожи, за исключением того, что в каждом случае они также применяют указанные подстановки к классам зависимостей - в этом случае, подводя их под org.elasticsearch.common
.
наконец-то filters
раздел исключает некоторые вещи из целевой банки, которые не должны быть там - например, метаданные JAR, файлы сборки ant, текстовые файлы и т. д. это упаковано с некоторыми зависимостями, но которые не принадлежат в банке uber.
<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>
небольшое предупреждение
хотя это не описывает, почему хотелось бы использовать Maven-shade-plugin (так как выбранный ответ описывает его довольно хорошо), я хотел бы отметить, что у меня были проблемы с ним. Он изменил банку (с тех пор, что она делает), и это вызвало регрессию в моем программном обеспечении.
Итак, вместо того, чтобы использовать это (или Maven-jarjar-plugin), я использовал двоичный файл JarJar, который, похоже, работает без проблем.
Я размещаю здесь мой решение, так как мне потребовалось некоторое время, чтобы найти достойное решение.
файл JAR Downlaod Джарджара
вы можете скачать jar-файл отсюда: https://code.google.com/p/jarjar/ В левом меню у вас есть ссылка, чтобы скачать ее.
Как использовать JarJar для перемещения классов банки из одного пакета в другой
в этом примере мы будем изменять пакет из " com.fasterxml.Джексон" в "Ио.кюкю.зависимостей.ком.fasterxml.Джексона". - Исходная банка называется " jackson-databind-2.6.4.jar "и новая модифицированная (целевая) банка называется" kuku-jackson-databind-2.6.4.сосуд." - Файл JAR" jarjar " находится в версии 1.4
создать "правила.txt-файл. Содержимое файла должно быть (смотрите период перед символом" @ ): правило com.fasterxml.Джексон.** io.kuku.dependencies.com.fasterxml.jackson.@1
выполните следующие действия команда: java-jar jarjar-1.4.правила процесса jar.txt jackson-databind-2.6.4.банку Куку-Джексон-привязку-2.6.4.Джар
установка измененных банок в локальный репозиторий
в этом случае я устанавливаю 3 файла, расположенные на "c:\my-jars \" папка.
МВН установки:Установка-файл -единственный способ иметь установленный=с:\мои-банки\Куку-Джексон-аннотации-2.6.4.jar-DgroupId=io.кюкю.зависимости-DartifactId=kuku-jackson-аннотации-Dversion=2.6.4 - Dpackaging=jar
mvn install:install-file-Dfile=C:\my-jars\kuku-jackson-core-2.6.4.jar-DgroupId=io.кюкю.зависимости-DartifactId=kuku-jackson-core-Dversion=2.6.4-Dpackaging=jar
МВН установки:Установка-файл -единственный способ иметь установленный=с:\мои-банки\Куку-Джексон-привязку-2.6.4.jar-DgroupId=io.кюкю.зависимости-DartifactId=kuku-jackson-аннотации-Dversion=2.6.4-Dpackaging=jar
использование измененных банок в POM проекта
в этом примере, это элемент "зависимости" в проектах 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>