Исключить все транзитивные зависимости одной зависимости

В Maven2, чтобы исключить одну транзитивную зависимость, я должен сделать что-то вроде этого:

<dependency>
  <groupId>sample.group</groupId>
  <artifactId>sample-artifactB</artifactId>
  <version>1</version>
   <exclusions>
     <exclusion>
       <groupId>sample.group</groupId>
       <artifactId>sample-artifactAB</artifactId>
     </exclusion>
   </exclusions>
</dependency>

Проблема с этим подходом заключается в том, что я должен делать это для каждой транзитивной зависимости, внесенной sample-artifactB.

Есть ли способ использовать какой-либо шаблон для исключения всех транзитивных зависимостей одновременно, а не один за другим?

Ответ 1

Для maven2 нет способа сделать то, что вы описали. Для maven 3 есть. Если вы используете maven 3, см. другой ответ на этот вопрос

Для maven 2 я бы рекомендовал создать собственный пользовательский pom для зависимости, в которой есть ваши < исключения > . Для проектов, которые должны использовать эту зависимость, задайте зависимость от вашего пользовательского pom вместо типичного артефакта. Хотя это не обязательно позволяет исключить все транзитивные зависимости с помощью одного исключения, оно позволяет вам только писать свою зависимость один раз, и все ваши проекты не должны содержать лишние и длинные списки исключений.

Ответ 2

Что сработало для меня (может быть, более новая функция Maven) - это просто делать подстановочные знаки в элементе исключения.

У меня есть проект с несколькими модулями, содержащий модуль "app", на который ссылаются в двух WAR-пакетах. Один из этих WAR-упакованных модулей действительно нуждается только в классах домена (и я еще не отделил их от модуля приложения). Я нашел это для работы:

<dependency>
    <groupId>${project.groupId}</groupId>
    <artifactId>app</artifactId>
    <version>${project.version}</version>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Подстановочный знак как для groupId, так и для artifactId исключает все зависимости, которые обычно распространяются на модуль с использованием этой зависимости.

Ответ 3

Одна вещь, которую я нашел полезной:

Если вы помещаете зависимость с исключениями в разделе dependencyManagement либо родительского POM для вашего проекта, либо в POM с изменяемой зависимостью, то вам не нужно повторять исключение (или версию).

Например, если ваш родительский POM имеет:

<dependencyManagement>
    <dependencies>
    ...         
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.1</version>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
     ....
  </dependencies>
</dependencyManagement>

Затем модули вашего проекта могут просто объявить зависимость как:

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>

В родительском POM указывается как версия, так и исключения. Я использую эту технику почти для всех наших проектов, и это устраняет много повторений.

Ответ 4

Три года назад Я рекомендовал использовать версию 99, не существует, но теперь я понял лучший способ, тем более что версия 99 находится в автономном режиме:

В своем родительском POM проекта используйте maven-enforcer-plugin, чтобы вывести из строя сборку, если нежелательная зависимость ползет в сборку. Это можно сделать с помощью правила плагина запрещенных зависимостей:

<plugin>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.0.1</version>
    <executions>
        <execution>
            <id>only-junit-dep-is-used</id>
            <goals>
                <goal>enforce</goal>
            </goals>
            <configuration>
                <rules>
                    <bannedDependencies>
                        <excludes>
                            <exclude>junit:junit</exclude>
                        </excludes>
                    </bannedDependencies>
                </rules>
            </configuration>
        </execution>
    </executions>
</plugin>

Затем, когда это оповещает вас о нежелательной зависимости, исключите его в родительский POM <dependencyManagement> раздел:

<dependency>
    <groupId>org.springframework.batch</groupId>
    <artifactId>spring-batch-test</artifactId>
    <version>2.1.8.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Таким образом, нежелательная зависимость не будет отображаться случайно (в отличие от просто <exclusion>, которую легко забыть), она не будет доступна даже во время компиляции (в отличие от области provided), нет фиктивных (в отличие от Версии 99), и он будет работать без специального репозитория (в отличие от Версии 99). Этот подход даже будет работать на основе версии артефакта, классификаторов, области или целого groupId - Подробнее см. В документации.

Ответ 5

В настоящее время нет способа исключить более чем одну транзитивную зависимость за раз, но на сайте Maven JIRA есть запрос функции:

https://issues.apache.org/jira/browse/MNG-2315

Ответ 6

Я использую следующее обходное решение: вместо попытки исключить артефакт во всех соответствующих зависимостях, я рисую зависимость как "предоставленную" на верхнем уровне. Например, чтобы избежать доставки xml-apis "любой версии":

    <dependency>
        <groupId>xml-apis</groupId>
        <artifactId>xml-apis</artifactId>
        <version>[1.0,]</version>
        <scope>provided</scope>
    </dependency>

Ответ 7

Существует обходной путь для этого, если вы установите область зависимости для среды выполнения, транзитивные зависимости будут исключены. Хотя имейте это в виду, это означает, что вам нужно добавить дополнительную обработку, если вы хотите упаковать зависимость времени выполнения.

Чтобы включить зависимость времени выполнения в любой упаковке, вы можете использовать плагин maven-dependency-plugin для определенного артефакта.

Ответ 8

если вам нужно исключить все транзитивные зависимости из артефакта зависимости, который вы собираетесь включить в сборку, вы можете указать это в дескрипторе для сборщика:

<assembly>
    <id>myApp</id>
    <formats>
        <format>zip</format>
    </formats>
    <dependencySets>
        <dependencySet>
            <useTransitiveDependencies>false</useTransitiveDependencies>
            <includes><include>*:struts2-spring-plugin:jar:2.1.6</include></includes>
        </dependencySet>
    </dependencySets>
</assembly>

Ответ 9

В чем причина исключения всех транзитивных зависимостей?

Если есть определенный артефакт (например, commons-logging), который вам нужно исключить из каждой зависимости, Версия 99 не существует может помочь.


Обновление 2012: Не используйте этот подход. Используйте maven-enforcer-plugin и исключения. Версия 99 создает фальшивые зависимости, а репозиторий версии 99 находится в автономном режиме (есть похожие зеркала, но вы не можете полагаться на них, чтобы оставаться в сети навсегда либо, лучше всего использовать только Maven Central).

Ответ 10

Если вы работаете в Eclipse, вы можете в графе зависимостей POM Editor (расширенные вкладки) посмотреть зависимость, которую вы хотите исключить из своего проекта, а затем:

щелкните правой кнопкой мыши по нему → "Исключить артефакт Maven...", и Eclipse сделает исключение для вас без необходимости выяснения зависимости зависимости, связанной с lib.

Ответ 11

В симулятивной проблеме у меня была запрошена заявленная зависимость с предоставленной областью. При таком подходе транзитивные зависимости извлекаются, но НЕ включаются в фазу пакета, что вам и нужно. Мне также нравится это решение с точки зрения обслуживания, потому что не существует pom или custom pom, как в решении whaley, которое необходимо поддерживать; вам нужно только указать конкретную зависимость в контейнере и выполнить

Ответ 12

Используйте последний maven в вашем пути к классу. Он удалит дубликаты артефактов и сохранит последний артефакт maven.

Ответ 13

Вы можете использовать exclude, но вам нужно вручную указать каждую зависимость, которую вы хотите исключить...

<dependency>
  <groupId>sample.group</groupId>
  <artifactId>sample-artifactB</artifactId>
  <version>1</version>
   <exclusions>
     <exclusion>
       <groupId>sample.group</groupId>
       <artifactId>sample-artifactAB</artifactId>
     </exclusion>
   </exclusions>
</dependency>