Maven Shaded Jar используется в качестве внешней зависимости проекта
Я использовал плагин maven shade в своем проекте, чтобы переместить все jar-классы зависимостей в один пакет, например org.shade. *
Когда я пытаюсь использовать этот затененный jar-файл в другом приложении в качестве maven-зависимости, он вытягивает jar-файл зависимости.
Я ожидаю, что когда убер / затененный jar включен как зависимость maven, он не должен вытягивать любой другой зависимый класс jar, так как уже эти классы переупакованы в затененный jar.
2 ответа
Классический сценарий:
- Проект, производящий uber-jar, имеет свои зависимости (
dependency
элементы в егоpom.xml
файл), которые затем упакованы в один супер-jar как артефакт Maven - При использовании этого uber-jar в качестве зависимости (
dependency
элемент) другого проекта, Maven будет затем проверять его<artifact>-<version>.pom
файл (опубликованный вместе с последним артефактом в хранилище Maven), который в основном является переименованной копией оригиналаpom.xml
файл, где зависимости (dependency
элемент) были объявлены (именно зависимости, упакованные в uber-jar). Так как вы уже собрали их, вам следует игнорировать
.pom
файл (и егоdependencies
элемент), для этого нужно добавитьexclusions
следующим образом:<dependency> <groupId>com.sample</groupId> <artifactId>something-uber</artifactId> <version>some-version</version> <exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency>
Примечание: вышеуказанная функция доступна только с Maven 3.2.1
,
Таким образом, вы даете понять Maven, что не хотите никакой транзитивной зависимости, и посредничество с зависимостями Maven не вызовет их.
В качестве примечания: не рекомендуется использовать Uber-jar в качестве зависимости проекта: это только усложнит обслуживание, поскольку вы не можете управлять переходными зависимостями с помощью dependencyManagement
или же dependencies
заказ зависимого проекта. Таким образом, вам всегда нужно будет повторно упаковать uber jar всякий раз, когда зависимость (одна из ее переходных) будет нуждаться в обслуживании (изменение версии и т. Д.) И иметь гораздо меньший контроль над зависимым проектом (опять же, более сложное обслуживание).
Поскольку файл pom.xml в вашем исходном проекте, который создает jar-файл uber, объявляет транзитивные зависимости, если вы включите его в качестве зависимости во внешний проект, Maven попытается получить их (даже если они уже включены в uber jar).
Я разделяю решение, которое позволяет вам избегать явного исключения всех транзитивных зависимостей, в том числе его, во внешний проект, как объяснил @A_DiMatteo в своем решении (я также согласен с ним относительно того, чтобы избегать использования uber jar в качестве зависимости, если в этом нет особой необходимости) по какой-то причине). В результате вы сможете включить свою зависимость от Uber JAR без использования элемента исключения, как показано ниже:
<dependency>
<groupId>com.sample</groupId>
<artifactId>something-uber</artifactId>
<version>some-version</version>
</dependency>
Предпосылка: моя цель состояла в том, чтобы предоставить как uber (без транзитивной зависимости, объявленной для pom), так и тонкие jar-файлы для моего хранилища. Таким образом, мое решение "А" основано на этом сценарии и в настоящее время имеет ограничение, которое затененная банка загружается 2 раза в хранилище.
- Чтобы обеспечить только Uber JAR см. Решение "B" ниже
- Для возможного решения для предела "A" см. Раздел ОБНОВЛЕНИЕ в конце
А) Предоставить как тонкие, так и супер-банки в хранилище
1- В исходном проекте настройте на своем модуле что-то pom.xml следующий maven-shade-plugin следующим образом:
<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>
<finalName>something-uber-${project.version}</finalName>
</configuration>
</execution>
</executions>
</plugin>
Затем используйте плагин build-helper-maven-plugin, чтобы прикрепить новый артефакт с классификатором "uber" к модулю:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>
${project.build.directory}/something-uber-${project.version}.jar
</file>
<classifier>uber</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
В результате этапа установки maven будут сгенерированы следующие два файла jar для target / directory:
40K something-0.1.0.jar
7M something-uber-0.1.0.jar
ПРЕДУПРЕЖДЕНИЕ: после выполнения фазы развертывания maven оба файла jar будут загружены в хранилище! Цель здесь должна состоять в том, чтобы выгрузить только развертывание с пропуском тонкой банки для затененной банки, чтобы оставить его в качестве локального артефакта (см. Раздел ОБНОВЛЕНИЕ в конце для возможного исправления)
2- Создайте тогда другой модуль в вашем исходном проекте с именем some-uber, добавив следующие зависимости и плагин:
<dependencies>
<dependency>
<groupId>com.sample</groupId>
<artifactId>something</artifactId>
<version>${project.version}</version>
<classifier>uber</classifier>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<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>
</execution>
</executions>
</plugin>
</plugins>
</build>
Обратите внимание на следующие сведения о включении зависимости:
- классификатор должен быть равен uber (тот, который вы указали, прикрепляя новый артефакт с помощью build-helper-maven-plugin в первом модуле)
- исключения уточняются.
В конце этапа развертывания maven на этом модуле затененный jar будет загружен в хранилище, и вы сможете добавить его в качестве зависимости во внешний проект следующим образом:
<dependency>
<groupId>com.sample</groupId>
<artifactId>something-uber</artifactId>
<version>0.1.0</version>
</dependency>
Б) Предоставить только Uber JAR на хранилище
Начиная с решения "А", если вы хотите избежать предоставления тонкой фляги в репозитории, вам следует избегать в пункте 1 указывать finalName в конфигурации maven-shade-plugin, поэтому избегайте также плагин build-helper-maven- plugin, поскольку новый артефакт для прикрепления. Делая это, при развертывании модуля у вас будет только Uber JAR на цели / по умолчанию (без классификатора):
7M something-0.1.0.jar
Вы также должны пропустить загрузку, в противном случае у вас также будут загружены две толстые фляги (что-то -0.1.0.jar и что-то - uber-0.1.0.jar). Для этого добавьте следующий плагин в тот же модуль:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
В конце пункта 2 просто избегайте указывать классификатор при добавлении зависимости следующим образом:
<dependencies>
<dependency>
<groupId>com.sample</groupId>
<artifactId>something</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
ОБНОВЛЕНИЕ: Пропустить первую затененную банку на решение А)
После некоторого безуспешного поиска решения я решил раскошелиться на плагин maven-deploy-plugin из GitHub и поработать над новой функцией, чтобы пропустить затененный jar, созданный в первом модуле, добавив плагин, настроенный следующим образом:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0-SNAPSHOT</version>
<configuration>
<skipAttachedArtifacts>
<artifact>
<groupId>com.sample</groupId>
<artifactId>something</artifactId>
<version>${project.version}</version>
<packaging>jar</packaging>
<classifier>uber</classifier>
</artifact>
</skipAttachedArtifacts>
</configuration>
</plugin>
В настоящее время с использованием плагина maven-deploy-plugin все артефакты исключаются из развертывания, в то время как цель здесь состоит в том, чтобы исключить только определенный. На своем форке я ввел параметр конфигурации "skipAttachedArtifacts", чтобы указать вложенные артефакты, которые нужно исключить из развертывания.
Вот ссылка на мой разветвленный проект на GitHub: https://github.com/gregorycallea/maven-deploy-plugin
Здесь ссылка вместо этого на запрос на отправку, который я отправил в проекте плагина apache: https://github.com/apache/maven-deploy-plugin/pull/3