Я обнаружил, что maven-shade-plugin используется в чьем-то файле pom.xml. Я никогда не использовал maven-shade-plugin раньше (и я Maven n00b), поэтому я попытался понять причину использования этого и что он делает.
Я посмотрел на документы Maven , однако не могу понять это утверждение:
«Этот плагин предоставляет возможность упаковать артефакт в uber-jar, включая его зависимости, и затемнить - т.е. переименовать - пакеты некоторых из зависимостей».
Документация на странице не выглядит очень удобной для новичков.
Что такое "Uber Jar?" Почему кто-то хочет сделать один? Какой смысл переименовывать пакеты зависимостей? Я попытался просмотреть примеры на странице apache maven-shade-plugin, такие как «Выбор содержимого для Uber Jar», но до сих пор не могу понять, что достигается с помощью «затенения».
Будем благодарны за любые указатели на иллюстративные примеры / варианты использования (с объяснением того, почему в этом случае требуется затенение - какую проблему оно решает). Наконец, когда я должен использовать плагин maven-shade-plugin?
источник
s/reallocation/relocation/
в приведенном выше комментарии.Ответы:
Короче говоря, Uber JAR - это JAR, содержащий все.
Обычно в Maven мы полагаемся на управление зависимостями. Артефакт содержит только свои классы / ресурсы. Maven будет нести ответственность за обнаружение всех артефактов (JAR и т. Д.), Которые будут выполняться в зависимости от проекта.
Uber-jar - это то, что берет все зависимости, извлекает содержимое зависимостей и помещает их вместе с классами / ресурсами самого проекта в один большой JAR. Имея такой uber-jar, его легко выполнить, потому что вам понадобится только один большой JAR вместо множества маленьких JAR для запуска вашего приложения. Это также облегчает распространение в некоторых случаях.
Просто примечание. Избегайте использования uber-jar в качестве зависимости Maven, так как это разрушает функцию разрешения зависимостей в Maven. Обычно мы создаем uber-jar только для конечного артефакта для фактического развертывания или для ручного распространения, но не для помещения в репозиторий Maven.
Обновление: я только что обнаружил, что не ответил ни на одну часть вопроса: «Какой смысл переименовывать пакеты зависимостей?». Вот несколько кратких обновлений и, надеюсь, поможет людям, имеющим аналогичные вопросы.
Создание Uber-JAR для простоты развертывания является одним из вариантов использования плагина Shade. Есть и другие распространенные случаи использования, которые включают переименование пакетов.
Например, я занимаюсь разработкой
Foo
библиотеки, которая зависит от конкретной версии (например, 1.0)Bar
библиотеки. Предполагая, что я не могу использовать другую версиюBar
lib (из-за изменения API или других технических проблем и т. Д.). Если я просто объявить ,Bar:1.0
какFoo
зависимость «S в Maven, можно попасть в проблему:Qux
проект в зависимости отFoo
, а такжеBar:2.0
(и это не может использовать ,Bar:1.0
потому чтоQux
потребности использовать новую функцию вBar:2.0
). Вот дилемма: следуетQux
использоватьBar:1.0
(какойQux
код не будет работать) илиBar:2.0
(какойFoo
код не будет работать)?Чтобы решить эту проблему, разработчик
Foo
может использовать плагин shade для переименования его использованияBar
, чтобы все классы вBar:1.0
jar были встроены вFoo
jar, а пакет встроенныхBar
классов был изменен сcom.bar
наcom.foo.bar
. При этомQux
может безопасно зависеть от того,Bar:2.0
потому что теперьFoo
больше не зависитBar
, и он использует свою собственную копию «изменен»,Bar
расположенный в другом пакете.источник
jar-with-dependency
дескриптор. Для решения проблемы зависимости с использованием uber-jar, я уже упоминал в своем ответе: не используйте uber-jar в качестве зависимости, точка. Немного подробнее: перед созданием uber-jar у вас должен быть обычный проект с нормальной зависимостью. Этот оригинальный артефакт следует использовать в качестве зависимости (вместо uber-jar)Class.forName
работать?Я недавно задавался вопросом, почему эластичный поиск затеняет и перемещает некоторые (но не все) его зависимости. Вот объяснение от сопровождающего проекта @kimchy :
- https://github.com/elasticsearch/elasticsearch/issues/2091#issuecomment-7156766
И еще один здесь от drewr :
- https://github.com/elasticsearch/elasticsearch/pull/3244#issuecomment-20125452
Итак, это один из вариантов использования. Что касается иллюстративного примера, ниже показано, как maven-shade-plugin используется в файле pse.xml эластичного поиска (v0.90.5). В
artifactSet::include
линии учи его , что зависимости тянуть в убер JAR ( в основном, они распаковали и и повторно упакованный ряд собственных классов elasticsearch, когда целевая elasticsearch банка производится. (В случае , если вы не знаете , это уже, баночка файл просто ZIP-файл, содержащий классы программы, ресурсы и т. д., а также некоторые метаданные. Вы можете извлечь один из них, чтобы увидеть, как он составлен.)Эти
relocations::relocation
строки похожи, за исключением того, что в каждом случае они также применяются указанные замены к классам зависимости в - в этом случае, в результате чего их подorg.elasticsearch.common
.Наконец, этот
filters
раздел исключает некоторые вещи из целевого JAR-файла, которых там быть не должно - такие как метаданные JAR, файлы сборки ant, текстовые файлы и т. Д., Которые упакованы с некоторыми зависимостями, но которые не входят в UAR-JAR.источник
Небольшое предупреждение
Хотя это не описывает, почему кто-то хотел бы использовать maven-shade-plugin (так как выбранный ответ описывает это довольно хорошо), я хотел бы отметить, что у меня были проблемы с ним. Это изменило JAR (так как это то, что он делает), и это вызвало регресс в моем программном обеспечении.
Итак, вместо того, чтобы использовать это (или maven-jarjar-plugin), я использовал бинарный файл JarJar, который, кажется, работает без проблем.
Я публикую здесь свое решение, так как мне потребовалось некоторое время, чтобы найти достойное решение.
Загрузите JAR-файл JarJar
Вы можете скачать банку отсюда: https://code.google.com/p/jarjar/ В левом меню у вас есть ссылка для его загрузки.
Как использовать JarJar для перемещения классов JAR из одного пакета в другой
В этом примере мы изменим пакет с «com.fasterxml.jackson» на «io.kuku.dependencies.com.fasterxml.jackson». - Исходный JAR называется "jackson-databind-2.6.4.jar", а новый модифицированный (целевой) JAR называется "kuku-jackson-databind-2.6.4.jar". - JAR-файл "jarjar" находится в версии 1.4
Создайте файл "rules.txt". Содержимое файла должно быть (следите за точкой перед символом '@'): правило com.fasterxml.jackson. ** io.kuku.dependencies.com.fasterxml.jackson. @ 1
Выполните следующую команду: java -jar jarjar-1.4.jar process rules.txt jackson-databind-2.6.4.jar kuku-jackson-databind-2.6.4.jar
Установка модифицированных JAR-файлов в локальный репозиторий
В этом случае я устанавливаю 3 файла, расположенных в папке "c: \ my-jars \".
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-annotations-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = kuku-jackson-annotations -Dversion = 2.6.4 - Dpackaging = баночка
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-core-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = kuku-jackson-core -Dversion = 2.6.4 - Dpackaging = баночка
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-databind-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = Куку-Джексон-аннотации -Dversion = 2.6.4 - Dpackaging = баночка
Использование модифицированных файлов JAR в pom проекта
В этом примере это элемент «dependencies» в проектах pom:
источник
Я думаю, что одним из примеров необходимости «затененной» банки является лямбда-функция AWS. Похоже, они позволяют загружать только 1 банку, а не всю коллекцию .jars, как вы могли бы найти в типичном файле .war. Итак, создание одного .jar со всеми зависимостями проекта позволяет вам сделать это.
источник