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

в 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 ответов


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

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


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

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

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

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


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

Если вы помещаете зависимость с исключениями в раздел 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>

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


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

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

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

затем, когда это предупреждает Вас о нежелательной зависимости, исключить его в Родительском пом :

<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). Этот подход будет работать даже на основе версии артефакта, классификаторов, области или целого groupId -посмотреть документация для сведения.


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

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

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

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


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

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


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

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

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

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


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

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


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


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


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


вы можете использовать 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>