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


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


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.


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


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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.