Исключить все переходные зависимости одной зависимости - PullRequest
201 голосов
/ 14 февраля 2009

В 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.

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

Ответы [ 13 ]

273 голосов
/ 26 сентября 2011

Что сработало для меня (может быть, новая функция 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 исключает все зависимости, которые обычно распространяются на модуль с использованием этой зависимости.

48 голосов
/ 14 февраля 2009

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

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

30 голосов
/ 14 февраля 2011

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

Если вы поместите зависимость с исключениями в раздел 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 будет указана версия и исключения. Я использую эту технику почти во всех наших проектах, и она исключает много повторений.

22 голосов
/ 01 мая 2012

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

В родительском POM вашего проекта используйте maven-forcecer-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>

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

<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 scope), фальшивых нет зависимости (в отличие от версии 99), и он будет работать без собственного хранилища (в отличие от версии 99). Этот подход будет работать даже на основе версии артефакта, классификаторов, области действия или целого идентификатора группы - подробности см. В документации .

10 голосов
/ 02 апреля 2013

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

    <dependency>
        <groupId>xml-apis</groupId>
        <artifactId>xml-apis</artifactId>
        <version>[1.0,]</version>
        <scope>provided</scope>
    </dependency>
9 голосов
/ 31 июля 2009

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

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

6 голосов
/ 27 февраля 2012

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

<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>
6 голосов
/ 31 июля 2009

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

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

3 голосов
/ 28 сентября 2011

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

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

3 голосов
/ 14 февраля 2009

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

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


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

...