Apakah ada cara untuk mengecualikan ketergantungan Maven secara global?

93

Saya mencoba menemukan cara "umum" untuk mengecualikan ketergantungan transitif agar tidak disertakan tanpa harus mengecualikannya dari semua ketergantungan yang bergantung padanya. Misalnya, jika saya ingin mengecualikan slf4j, saya melakukan hal berikut:

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

Ini sebagian untuk membersihkan file pom, sebagian untuk menghindari masalah di masa mendatang dengan orang-orang yang menambahkan dependensi yang bergantung pada dependensi yang dikecualikan itu - dan lupa mengecualikannya.

Apakah ada jalan

Sébastien Le Callonnec
sumber
2
Tidak menyelesaikan masalah, tetapi maven-penegak-plugin memiliki fitur dependensi terlarang yang akan gagal membangun jika dependensi yang tidak diinginkan menyelinap masuk. Anda masih harus mengecualikannya secara manual, meskipun: - /
dnault
Jawaban alternatif tersedia di sini: stackoverflow.com/a/39979760/363573
Stephan

Jawaban:

69

Apakah ini membantu? http://jlorenzen.blogspot.com/2009/06/maven-global-excludes.html

"Dengan asumsi saya ingin mengecualikan avalon-framework dari WAR saya, saya akan menambahkan yang berikut ini ke project POM saya dengan cakupan yang disediakan. Ini berfungsi di semua dependensi transitif dan memungkinkan Anda untuk menentukannya sekali.

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

Ini bahkan berfungsi saat menentukannya di POM induk, yang akan mencegah proyek untuk mendeklarasikannya di semua POM turunan. "

Joffer
sumber
49
Ini masih hanya peretasan parsial - ketergantungan tidak akan berakhir di dalam artefak build tetapi masih tersedia selama pengujian.
Tuukka Mustonen
@TuukkaMustonen Bagaimana dengan runtimeruang lingkup, bukan providedruang lingkup?
Stephan
Apa yang terjadi jika avalon-framework 4.1.3+ disertakan di bagian lain dalam proyek ini? Lihat tanggapan di sini: stackoverflow.com/a/39979760/363573
Stephan
Saya tidak menggunakan Maven lagi jadi saya tidak dalam posisi untuk menguji jawaban lain, tetapi saya akan mendorong orang-orang untuk mempertimbangkannya jika ada yang bukan peretasan parsial, sesuai @TuukkaMustonen
Joffer
18

Saya membuat toples kosong dan membuat ketergantungan ini:

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

Ini tidak sempurna karena mulai sekarang Anda memiliki tabung kosong di jalur kompilasi / pengujian Anda. Tapi itu hanya kosmetik.

Guus Bloemsma
sumber
3
systemscope sekarang tidak digunakan lagi: maven.apache.org/guides/introduction/…
Jason Young
Untuk menghindari penggunaan systemcakupan, lihat repositori Maven virtual version99.grons.nl (Peringatan: hanya HTTP) atau (hanya untuk pencatatan umum / log4j) lihat "alternatif 3) artefak kosong" di sini: slf4j.org/faq.html#excludesJCL
seanf
16

Untuk memperluas komentar dnault :

Seseorang dapat menggunakan aturan Banned Dependencies dari plugin Maven Enforcer untuk memastikan dependensi dikecualikan. Anda masih harus mengecualikannya secara manual, tetapi build akan gagal jika ada yang salah menambahkan dependensi di tempat lain.

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

Juga ada permintaan fitur terbuka: MNG-1977 Pengecualian ketergantungan global

Arend v. Reinersdorff
sumber
2
Mengikuti jawaban Anda dan membaca diskusi dari tautan yang Anda berikan, saya menyadari guci yang tidak diinginkan masuk ke guci lemak beberapa kali hanya karena versi maven yang digunakan di lokal dan di server berbeda sehingga logika pengemasan dapat menambahkan versi yang sangat berbeda dari dependensi jika tidak diterapkan secara ketat. Untuk mengatasi masalah serupa, saya menggunakan konfigurasi spring-boot-maven-plugin / excludes / exclude untuk <goal> repackage </goal>.
aprodan
10

Sebagai pengingat, berikut adalah jawaban dari dokumentasi resmi Maven:

Mengapa pengecualian dibuat berdasarkan ketergantungan, bukan di tingkat POM

Ini terutama dilakukan untuk memastikan grafik ketergantungan dapat diprediksi, dan untuk menjaga efek pewarisan agar tidak mengecualikan ketergantungan yang tidak boleh dikecualikan. Jika Anda sampai ke metode pilihan terakhir dan harus memasukkan pengecualian, Anda harus benar-benar yakin mana dari ketergantungan Anda yang membawa ketergantungan transitif yang tidak diinginkan itu.

Jika seseorang ingin membuat build lebih kuat, rentang versi dapat digunakan. Ini akan memastikan bahwa tidak ada versi terbaru dari ketergantungan yang dapat mengganggu proyek.

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

Setiap versi slf4j-api> = 1.4.2 akan dianggap sebagai ditawarkan (disediakan) pada waktu proses, baik dari classpath atau penampung yang dikonfigurasi.

Referensi

Stephan
sumber