Чи є спосіб виключити залежність Maven у всьому світі?


92

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

  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jmx</artifactId>
    <version>3.3.2.GA</version>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>3.4.0.GA</version>
    <type>jar</type>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

Це частково для очищення файлу pom, частково для уникнення проблем у майбутньому, коли люди додають залежності, які залежать від цієї виключеної залежності, - і забуваючи виключити її.

Чи є спосіб?


2
Проблема не вирішує, але плагін maven-princer має заборонену функцію залежностей, яка не зможе побудувати, якщо потраплять небажані залежності. Однак вам все одно доведеться їх виключити вручну: - /
dnault

Альтернативна відповідь доступна тут: stackoverflow.com/a/39979760/363573
Стефан

Відповіді:


69

Це допомагає? http://jlorenzen.blogspot.com/2009/06/maven-global-excludes.html

"Припускаючи, що я хочу виключити avalon-framework з моєї WAR, я б додав наступне до своїх проектів POM із зазначеним обсягом. Це працює в усіх перехідних залежностях і дозволяє вам вказати його один раз.

<dependencies>
  <dependency>
      <artifactId>avalon-framework</artifactId>
      <groupId>avalon-framework</groupId>
      <version>4.1.3</version>
      <scope>provided</scope>
  </dependency>
</dependencies>

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


49
Це все-таки лише частковий злом - залежність не потрапить всередину артефакту збірки, але вона все ще доступна під час тестів.
Туукка Мустонен

@TuukkaMustonen Що можна сказати про runtimeсферу замість providedсфери?
Стефан

Що трапиться, якщо avalon-framework 4.1.3+ включений деінде в проект? Дивіться відповідь тут: stackoverflow.com/a/39979760/363573
Стефан

Я більше не використовую Maven, тому я не в змозі перевірити інші відповіді, але я б закликав людей розглянути їх на випадок, якщо є такий, який не є частковим злом, згідно @TuukkaMustonen
Joffer

18

Я створив порожню банку і створив таку залежність:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <scope>system</scope>
    <systemPath>${basedir}/src/lib/empty.jar</systemPath>
    <version>0</version>
</dependency>

Це не ідеально, тому що відтепер у вашому шляху компіляції / тесту є порожня банка. Але це просто косметика.


3
systemСфера застосування застаріла: maven.apache.org/guides/introduction/…
Джейсон Янг,

Щоб уникнути використання systemобласті, див. Віртуальне сховище Maven version99.grons.nl (Попередження: лише HTTP) або (лише для commons-logging / log4j) див. "Альтернатива 3) порожні артефакти" тут: slf4j.org/faq.html#excludingJCL
Шонф

16

Щоб розширити коментар dnault :

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

<dependencies>
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jmx</artifactId>
    <version>3.3.2.GA</version>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
</dependencies>

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.4.1</version>
    <executions>
      <execution>
        <goals>
          <goal>enforce</goal>
        </goals>
        <configuration>
          <rules>
            <bannedDependencies>
              <excludes>
                <exclude>org.slf4j:slf4j-api</exclude>
              </excludes>
            </bannedDependencies>
          </rules>
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>

Також є відкритий запит на функцію: MNG-1977 Глобальне виключення залежностей


2
Після вашої відповіді та прочитання обговорення за посиланням, яке ви надали, я зрозумів, що небажані баночки кілька разів потрапляють у жирову банку лише тому, що версія maven, яка використовується на локальному та на сервері, відрізняється, тому логіка упаковки може додавати різні версії залежностей, якщо вони не дотримуються суворо. Для вирішення моєї подібної проблеми я використовував конфігурацію spring-boot-maven-plugin / excludes / exclude для <goal> repackage </goal>.
aprodan

10

Нагадаємо, ось відповідь з офіційної документації Maven:

Чому виключення здійснюються на основі залежності, а не на рівні POM

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

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

<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>[1.4.2,)</version>
   <scope>provided</scope>
</dependency>

Будь-яка версія slf4j-api> = 1.4.2 вважатиметься такою, що пропонується (надається) під час виконання, або з налаштованого шляху до класу, або з контейнера.

Список літератури

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