1. Gambaran keseluruhan
Projek Maven pelbagai modul boleh mempunyai grafik pergantungan yang kompleks. Ini boleh memberikan hasil yang luar biasa, semakin banyak modul yang diimport antara satu sama lain.
Dalam tutorial ini, kita akan melihat cara menyelesaikan pelanggaran artifak versi di Maven .
Kita akan mulakan dengan projek pelbagai modul di mana kita sengaja menggunakan pelbagai versi artifak yang sama. Kemudian, kita akan melihat cara mencegah mendapatkan artifak versi yang salah dengan pengurusan pengecualian atau pergantungan.
Akhirnya, kami akan cuba menggunakan plugin m aven-نافذ untuk membuat perkara lebih mudah dikawal, dengan melarang penggunaan pergantungan transitif.
2. Versi Perlanggaran Artifak
Setiap kebergantungan yang kami sertakan dalam projek kami mungkin berkaitan dengan artifak lain. Maven secara automatik dapat membawa artifak ini, juga disebut pergantungan transitif. Perlanggaran versi berlaku apabila beberapa kebergantungan menghubungkan ke artifak yang sama, tetapi menggunakan versi yang berbeza.
Akibatnya, mungkin terdapat kesalahan dalam aplikasi kami baik dalam fasa penyusunan dan juga pada waktu proses .
2.1. Struktur Projek
Mari tentukan struktur projek pelbagai modul untuk dicuba. Projek kami terdiri daripada modul perlanggaran versi induk dan tiga anak:
version-collision project-a project-b project-collision
The pom.xml untuk projek-a dan projek-b adalah hampir sama. Satu-satunya perbezaan adalah versi artifak com.google.guava yang mereka andalkan. Khususnya, projek-a menggunakan versi 22.0 :
com.google.guava guava 22.0
Tetapi, projek-b menggunakan versi yang lebih baru, 29.0-jre :
com.google.guava guava 29.0-jre
Modul ketiga, perlanggaran projek , bergantung pada dua yang lain:
com.baeldung project-a 0.0.1-SNAPSHOT com.baeldung project-b 0.0.1-SNAPSHOT
Jadi, versi jambu manakah yang akan tersedia untuk perlanggaran projek ?
2.2. Menggunakan Ciri dari Versi Ketergantungan Khusus
Kita dapat mengetahui kebergantungan mana yang digunakan dengan membuat ujian mudah dalam modul perlanggaran projek yang menggunakan kaedah Futures.immediateVoidFuture dari jambu batu :
@Test public void whenVersionCollisionDoesNotExist_thenShouldCompile() { assertThat(Futures.immediateVoidFuture(), notNullValue()); }
Kaedah ini hanya tersedia dari versi 29.0-jre . Kami mewarisi ini dari salah satu modul lain, tetapi kami hanya dapat menyusun kod kami jika kami mendapat pergantungan transitif dari projek-b.
2.3. Ralat Penyusunan Disebabkan oleh Perlanggaran Versi
Bergantung pada susunan kebergantungan dalam modul perlanggaran projek , dalam kombinasi tertentu Maven mengembalikan ralat kompilasi:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:testCompile (default-testCompile) on project project-collision: Compilation failure [ERROR] /tutorials/maven-all/version-collision/project-collision/src/test/java/com/baeldung/version/collision/VersionCollisionUnitTest.java:[12,27] cannot find symbol [ERROR] symbol: method immediateVoidFuture() [ERROR] location: class com.google.common.util.concurrent.Futures
Itulah hasil pelanggaran versi artifak com.google.guava . Secara lalai, untuk kebergantungan pada tahap yang sama di pohon pergantungan, Maven memilih perpustakaan pertama yang dijumpainya. Dalam kes kami, kedua-dua kebergantungan com.google.guava berada pada ketinggian yang sama dan versi yang lebih lama dipilih.
2.4. Menggunakan maven-dependency-plugin
The Maven-pergantungan-plugin adalah alat yang sangat berguna untuk membentangkan semua kebergantungan dan versi mereka:
% mvn dependency:tree -Dverbose [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ project-collision --- [INFO] com.baeldung:project-collision:jar:0.0.1-SNAPSHOT [INFO] +- com.baeldung:project-a:jar:0.0.1-SNAPSHOT:compile [INFO] | \- com.google.guava:guava:jar:22.0:compile [INFO] \- com.baeldung:project-b:jar:0.0.1-SNAPSHOT:compile [INFO] \- (com.google.guava:guava:jar:29.0-jre:compile - omitted for conflict with 22.0)
The -Dverbose memaparkan bendera bercanggah artifak. Sebenarnya, kami mempunyai kebergantungan com.google.guava dalam dua versi: 22.0 dan 29.0-jre. Yang terakhir adalah yang ingin kita gunakan dalam modul perlanggaran projek .
3. Tidak termasuk Pergantungan Transitif Dari Artifak
Salah satu cara untuk menyelesaikan pelanggaran versi adalah dengan menghilangkan pergantungan transitif yang bertentangan dari artifak tertentu . Dalam contoh kami, kami tidak mahu perpustakaan com.google.guava ditambahkan secara sementara dari projek- artifak.
Oleh itu, kita boleh mengecualikannya dalam pom perlanggaran projek :
com.baeldung project-a 0.0.1-SNAPSHOT com.google.guava guava com.baeldung project-b 0.0.1-SNAPSHOT
Sekarang, apabila kita menjalankan pergantungan: arahan pokok , kita dapat melihat bahawa tidak ada lagi:
% mvn dependency:tree -Dverbose [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ project-collision --- [INFO] com.baeldung:project-collision:jar:0.0.1-SNAPSHOT [INFO] \- com.baeldung:project-b:jar:0.0.1-SNAPSHOT:compile [INFO] \- com.google.guava:guava:jar:29.0-jre:compile
Hasilnya, fasa penyusunan berakhir tanpa ralat dan kita dapat menggunakan kelas dan kaedah dari versi 29.0-jre .
4. Menggunakan dependencyManagement Seksyen
Maven's dependencyManagement bahagian adalah mekanisme untuk memusatkan maklumat ketergantungan . Salah satu ciri yang paling berguna adalah untuk mengawal versi artifak yang digunakan sebagai pergantungan transitif.
Dengan ini, mari buat konfigurasi dependencyManagement di pom induk kami :
com.google.guava guava 29.0-jre
Hasilnya, Maven akan pastikan anda menggunakan versi 29.0-jre daripada com.google.guava artifak dalam semua modul kanak-kanak:
% mvn dependency:tree -Dverbose [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ project-collision --- [INFO] com.baeldung:project-collision:jar:0.0.1-SNAPSHOT [INFO] +- com.baeldung:project-a:jar:0.0.1-SNAPSHOT:compile [INFO] | \- com.google.guava:guava:jar:29.0-jre:compile (version managed from 22.0) [INFO] \- com.baeldung:project-b:jar:0.0.1-SNAPSHOT:compile [INFO] \- (com.google.guava:guava:jar:29.0-jre:compile - version managed from 22.0; omitted for duplicate)
5. Mencegah Ketergantungan Transitif Tidak Sengaja
The maven-enforcer-plugin provides many built-in rules that simplify the management of a multi-module project. One of them bans the use of classes and methods from transitive dependencies.
Explicit dependency declaration removes the possibility of version collision of artifacts. Let's add the maven-enforcer-plugin with that rule to our parent pom:
org.apache.maven.plugins maven-enforcer-plugin 3.0.0-M3 enforce-banned-dependencies enforce
As a consequence, we must now explicitly declare the com.google.guava artifact in our project-collision module if we want to use it ourselves. We must either specify the version to use, or set up dependencyManagement in the parent pom.xml. This makes our project more mistake proof, but requires us to be more explicit in our pom.xml files.
6. Conclusion
In this article, we've seen how to resolve a version collision of artifacts in Maven.
First, we explored an example of a version collision in a multi-module project.
Kemudian, kami menunjukkan cara mengecualikan pergantungan transitif dalam pom.xml . Kami melihat cara mengawal versi dependensi dengan bahagian dependencyManagement di pom.xml induk .
Akhirnya, kami mencuba plugin penguat kuasa untuk melarang penggunaan pergantungan transitif untuk memaksa setiap modul untuk mengendalikan sendiri.
Seperti biasa, kod yang ditunjukkan dalam artikel ini terdapat di GitHub.