Виключити всі перехідні залежності однієї залежності


221

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

Чи є можливість використовувати якусь підстановку, щоб одразу виключити всі перехідні залежності замість однієї за одною?


Часом потрібно використовувати останню версію бібліотеки, наприклад, Spring 2.5.6, але деякі інші залежності включають старішу версію, наприклад, struts2-spring-plugin (2.1.6) включає Spring 2.5.3. У таких сценаріях існує вимога щодо виключення або переопределення версії.
Вінод Сінгх

1
Використовуйте плющ. Жартую.
Джейк Торонто

Відповіді:


54

Для maven2 не існує способу зробити те, що ви описуєте. Для maven 3 є. Якщо ви використовуєте maven 3, будь ласка, подивіться іншу відповідь на це питання

Для Maven 2 я рекомендую створити власний користувальницький пом на залежність, яка має ваші <винятки>. Для проектів, яким потрібно використовувати цю залежність, встановіть залежність на свій власний пом замість типового артефакту. Хоча це не обов'язково дозволяє виключати всі перехідні залежності одним <виключенням>, це дозволяє лише писати залежність лише один раз, і всі ваші проекти не потребують ведення зайвих і довгих списків виключень.


12
Я б рекомендував не робити власну помпону, щоб обійти виключення. Це робить вашу конструкцію набагато менш портативною та зменшує розуміння.
Брайан Фокс

1
У випадку, якщо ви не дивитесь на минулого прийнятого вражника: jira.codehaus.org/browse/MNG-3832
Якуб

@JakubBochenski відповідь, яку я дав, є специфічною для maven 2, саме на це і позначено це питання (під час написання цього коментаря). Ваше посилання стосується лише Maven 3. Незважаючи на те, я змінив свою відповідь на посилання, щоб посилатися на більш високообороту відповідь.
кит

306

Те, що для мене спрацювало (можливо, це є новішою рисою Maven), - це лише те, щоб зробити символи підкреслення в елементі виключення.

У мене є багатомодульний проект, який містить модуль "додаток", на який посилаються два модулі, упаковані у ВІЙНУ. Один з цих модулів, укомплектованих WAR, справді потребує лише класів доменів (і я їх ще не відокремлював від модуля програми). Я виявив, що це працює:

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

Підстановочний знак як для groupId, так і для artifactId виключає всі залежності, які зазвичай поширюються на модуль, використовуючи цю залежність.


9
* Макіяж для групових та штучних робіт, здається, працює в maven 3
nkr1pt

22
Я не знаю, як вам вдалося це знайти, оскільки Maven 3 явно попереджає про використання зірочки: [ПОПЕРЕДЖЕННЯ] 'зависимости.dependency.excptions.exclusion.groupId' for <artifcat_id> зі значенням "*" не відповідає відповідати дійсному шаблону id. [УВАГА] Настійно рекомендується виправити ці проблеми, оскільки вони загрожують стабільності вашої збірки. [ПОПЕРЕДЖЕННЯ] З цієї причини майбутні версії Maven більше не підтримуватимуть створення таких неправомірних проектів. Не хотіли б ви надати деякі докази того, що він підтримується та може бути використаний? Інакше я вважаю ваш коментар надзвичайно оманливим.
ᄂ ᄀ

7
Чудово працював з Maven 3.0.4. Спасибі велике !
Євгеній Голдін

1
maven 3.0.4 -> це не добре працювало для мене. в результаті баночка дуже сильно відрізняється, коли я використовую asterix або коли я прямо виключаю всі прямі залежності. це може бути пов'язане з тим, що я використовую плагін Maven-Assembly-плагін для створення жирової баночки. у цьому випадку запропонована сулоція не працює!
gilad hoch

31
Цей метод є дійсним. Вони виправили попередження про те, що інші звітують у Maven 3.2.1: issues.apache.org/jira/browse/MNG-3832
Ryan

32

Одне я вважаю корисним:

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


23

Три роки тому я рекомендував використовувати Версію 99 Не існує, але зараз я придумав кращий спосіб, тим більше, що Версія 99 офлайн:

У батьківському POM вашого проекту використовуйте плагін maven-Execucer для відмови збірки, якщо небажана залежність проникає в збірку. Це можна зробити за допомогою правила заборонених залежностей плагіна :

<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). Цей підхід працюватиме навіть на основі версії артефакту, класифікаторів, сфери застосування або цілої групиId - детальну інформацію див. У документації .


Зауважте, що принаймні під Maven 3.1 цей <configuration>елемент ігнорується при виконанні мети з командного рядка, і його потрібно переміщувати прямо під <plugin>.
Девід Харкнесс

Щойно я виявив, як виглядає неприємна помилка Maven - версія 3.5.2. У мене є проект із підмодулями, де я виключаю залежність на батьківському <dependencyManagement>розділі. Запуск mvn dependency:treeцього конкретного проекту взагалі не матиме виключеної залежності. Але всі проекти, які імпортують цю залежність, не будуть шанувати <exclusions>інших інших батьківських проектів - виключений буде повзати !!! Мені довелося безпосередньо перейти <exclusions>до кожного модуля пом.
cbaldan

11

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

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


6

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

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


1
Це допомогло мені вирішити проблеми із компілятором Android Dalvik, який не міг обробити деякі дворівневі транзитивні включення ---, але мені довелося використовувати <scope>provided</scope>замість цього <scope>runtime</scope>.
Гаррет Вілсон

6

якщо вам потрібно виключити всі перехідні залежності з артефакту залежності, який ви збираєтеся включити в збірку, ви можете вказати це в дескрипторі збірки-плагіна:

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

3

Якщо ви розробляєтесь у програмі Eclipse, ви можете в графіку залежності редактора POM (увімкнені розширені вкладки) шукати залежність, яку ви хочете виключити зі свого проекту, а потім:

клацніть правою кнопкою миші на ньому -> "Виключити артефакт Maven ...", і Eclipse зробить виключення для вас без необхідності з'ясовувати, на яку залежність пов’язана ліба.


зауважте, що це працює лише в тому випадку, якщо ви використовуєте плагін m2eclipse
Nicolas Mommaerts

2

Яка ваша причина виключення всіх перехідних залежностей?

Якщо є певний артефакт (наприклад, загальнодоступний журнал), який потрібно виключити з кожної залежності, підхід Версії 99 не існує .


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


1

У модельному питанні я мав бажану залежність, заявлену із наданим обсягом. При такому підході транзитивні залежності дістаються, але НЕ включаються до фази пакету, що саме ви хочете. Мені також подобається це рішення з точки зору технічного обслуговування, тому що немає ні помпону, ні спеціального пам’ятника, як у розчині Кейлі, необхідного для підтримання; вам потрібно лише вказати конкретну залежність у контейнері і це зробити


-2

Використовуйте останню Maven на своєму classpath .. Це видалить дублікати артефактів і збереже останній артефакт Maven ..

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.