Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Artikel ini menjelaskan konflik versi dependensi dan cara memecahkan masalahnya.
Pustaka klien Azure untuk Java bergantung pada pustaka pihak ketiga populer seperti yang berikut ini:
Banyak aplikasi dan kerangka kerja Java menggunakan pustaka ini secara langsung atau transitif, yang menyebabkan konflik versi. Manajer dependensi seperti Maven dan Gradle menyelesaikan semua dependensi sehingga hanya ada satu versi dari setiap dependensi pada classpath. Namun, tidak dijamin bahwa versi dependensi yang diselesaikan kompatibel dengan semua konsumen dependensi tersebut dalam aplikasi Anda. Untuk informasi selengkapnya, lihat Pengenalan Mekanisme Dependensi dalam dokumentasi Maven dan Memahami resolusi dependensi dalam dokumentasi Gradle.
Ketidaksesuaian API dari dependensi langsung menghasilkan kesalahan kompilasi. Ketidakcocokan dependensi diamond biasanya mengakibatkan kegagalan runtime seperti NoClassDefFoundError, NoSuchMethodError, atau LinkageError lainnya. Tidak semua pustaka secara ketat mengikuti penerapan versi semantik, dan perubahan yang melanggar terkadang terjadi dalam versi utama yang sama.
Mendiagnosis masalah ketidakcocokan versi
Bagian berikut menjelaskan metode tentang cara mendiagnosis masalah ketidakcocokan versi.
Gunakan alat build Java Azure SDK
Alat build Azure SDK for Java, yang diperkenalkan di Mulai menggunakan Azure SDK dan Apache Maven, membantu mengidentifikasi masalah yang umum ditemui. Kami menyarankan agar Anda menambahkan alat build ini ke proyek Anda dan menjalankannya dengan menambahkan azure:run
target Maven ke proses build reguler Anda. Dengan konfigurasi yang sesuai, Anda dapat mengidentifikasi dan menyelesaikan konflik dependensi secara lebih proaktif, sebelum menjadi masalah saat runtime.
Menampilkan pohon dependensi
Jalankan mvn dependency:tree
atau gradle dependencies --scan
untuk menampilkan pohon dependensi lengkap untuk aplikasi Anda, dengan nomor versi.
mvn dependency:tree -Dverbose
memberikan informasi lebih lanjut, tetapi mungkin menyesatkan. Untuk informasi selengkapnya, lihat Pohon Dependensi Apache Maven dalam dokumentasi Maven. Untuk setiap pustaka yang Anda duga memiliki konflik versi, perhatikan nomor versinya dan tentukan komponen mana yang bergantung padanya.
Resolusi dependensi dalam lingkungan pengembangan dan produksi dapat bekerja secara berbeda. Plugin Apache Spark, Apache Flink, Databricks, dan IDE memerlukan konfigurasi ekstra untuk dependensi kustom. Mereka juga dapat membawa versi pustaka Klien Azure mereka sendiri atau komponen umum. Untuk informasi lebih lanjut, baca artikel berikut:
- Bundling Dependensi Aplikasi Anda untuk Apache Spark
- Konfigurasi Proyek untuk Apache Flink
- Cara memperbarui pustaka Maven dengan benar di Databricks for Databricks
Untuk informasi selengkapnya tentang resolusi konflik di lingkungan tersebut, lihat bagian Create a fat JAR di artikel ini nanti.
Mengonfigurasi Azure Functions
Versi dependensi internal pada Azure Functions (hanya menjalankan Java 8) lebih diutamakan daripada yang disediakan pengguna. Dependensi ini menyebabkan konflik versi, terutama dengan Jackson, Netty, dan Reactor.
Untuk mengatasi masalah ini, atur FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS
variabel lingkungan ke true
atau 1
. Pastikan untuk memperbarui Azure Function Tools (v2 atau v3) ke versi terbaru.
Nota
Konfigurasi ini hanya berlaku untuk Azure Functions yang menjalankan Java 8, Functions yang menjalankan Java 11 tidak memerlukan konfigurasi khusus.
Mengonfigurasi Apache Spark
Azure SDK untuk Java mendukung beberapa versi Jackson, tetapi masalah terkadang dapat muncul tergantung pada alat build Anda dan urutan resolusi dependensinya. Contoh yang baik dari masalah ini adalah dengan Apache Spark, versi 3.0.0 dan yang lebih baru, yang tergantung pada Jackson 2.10. Meskipun kompatibel dengan Azure SDK untuk Java, pengembang sering menemukan bahwa versi Jackson yang lebih baru digunakan sebagai gantinya, yang menghasilkan ketidakcocokan. Untuk mengurangi masalah ini, Anda harus menyematkan versi Jackson tertentu (yang kompatibel dengan Spark). Untuk informasi selengkapnya, lihat bagian Dukungan untuk beberapa versi Jackson di artikel ini.
Jika Anda menggunakan versi Spark yang lebih lama, atau jika pustaka lain yang Anda gunakan memerlukan versi Jackson yang lebih lama yang tidak didukung Azure SDK for Java, lanjutkan membaca artikel ini untuk langkah-langkah mitigasi yang mungkin.
Mendeteksi versi runtime pada Jackson
Pada Azure Core 1.21.0, kami menambahkan deteksi waktu jalan dan diagnostik yang lebih baik dari versi runtime Jackson.
Jika Anda melihat LinkageError
(atau salah satu subkelasnya) yang terkait dengan JACKSON API, periksa pesan pengecualian untuk informasi versi runtime. Misalnya: com.azure.core.implementation.jackson.JacksonVersionMismatchError: com/fasterxml/jackson/databind/cfg/MapperBuilder Package versions: jackson-annotations=2.9.0, jackson-core=2.9.0, jackson-databind=2.9.0, jackson-dataformat-xml=2.9.0, jackson-datatype-jsr310=2.9.0, azure-core=1.19.0-beta.2
Cari log peringatan dan kesalahan dari JacksonVersion
. Untuk informasi selengkapnya, lihat Mengonfigurasi pengelogan di Azure SDK untuk Java. Misalnya: [main] ERROR com.azure.core.implementation.jackson.JacksonVersion - Version '2.9.0' of package 'jackson-core' is not supported (too old), please upgrade.
Nota
Periksa apakah semua paket Jackson memiliki versi yang sama.
Untuk daftar paket yang digunakan oleh Azure SDK dan versi Jackson yang didukung, lihat bagian Dukungan untuk beberapa versi Jackson .
Mengurangi masalah ketidakcocokan versi
Bagian berikut menjelaskan cara mengurangi masalah ketidakcocokan versi.
Menggunakan Azure SDK BOM
Gunakan Azure SDK BOM stabil terbaru dan jangan tentukan Azure SDK dan versi dependensi dalam file POM Anda. Jika berlaku, gunakan Azure Spring Boot BOM.
Dependensi yang tercantum dalam Azure SDK BOM diuji secara ketat untuk menghindari konflik dependensi.
Hindari dependensi yang tidak perlu
Hapus dependensi jika Anda bisa. Terkadang, aplikasi memiliki dependensi pada beberapa pustaka yang pada dasarnya menyediakan fungsionalitas yang sama. Dependensi yang tidak perlu tersebut mengekspos aplikasi terhadap kerentanan keamanan, konflik versi, dan biaya dukungan dan pemeliharaan.
Memperbarui versi dependensi
Jika beralih ke Azure SDK BOM terbaru tidak membantu, identifikasi pustaka yang menyebabkan konflik dan komponen yang menggunakannya. (Untuk informasi selengkapnya, lihat bagian Menampilkan pohon dependensi sebelumnya di artikel ini.) Coba perbarui ke versi yang lebih baru, yang melindungi dari kerentanan keamanan, dan sering membawa fitur baru, peningkatan performa, dan perbaikan bug.
Hindari menurunkan versi Azure SDK karena dapat mengekspos aplikasi Anda terhadap kerentanan dan masalah yang diketahui.
Pustaka bayangan
Terkadang tidak ada kombinasi pustaka yang dapat bekerja bersama, dan teknik shading menjadi pilihan terakhir.
Nota
Bayangan memiliki kelemahan yang signifikan: meningkatkan ukuran paket dan jumlah kelas pada classpath, membuat navigasi kode dan penelusuran kesalahan menjadi sulit, tidak merelokasi kode JNI, memutus refleksi, dan dapat melanggar lisensi kode dan lain-lain. Ini harus digunakan hanya setelah opsi lain habis.
"Shading memungkinkan Anda menyertakan dependensi dalam JAR pada waktu build, lalu mengganti nama paket dan memperbarui kode aplikasi untuk menggunakan kode di lokasi shading." Konflik dependensi berlian tidak lagi menjadi masalah karena ada dua salinan dependensi yang berbeda. Anda dapat mengelola pustaka yang memiliki dependensi transitif yang bertentangan atau dependensi langsung pada aplikasi, seperti yang dijelaskan dalam daftar berikut:
-
Konflik dependensi transitif: Misalnya, pustaka
A
pihak ketiga memerlukan Jackson 2.9, yang tidak didukung Azure SDK, dan tidak dimungkinkan untuk memperbaruiA
. Buat modul baru, yang mencakupA
dan bayangan (relokasi) Jackson 2.9 dan, opsional, dependensi lain dariA
. - Konflik ketergantungan aplikasi: Aplikasi Anda menggunakan Jackson 2.9 langsung. Saat Anda sedang memperbarui kode, Anda dapat menggunakan shading dan memindahkan Jackson 2.9 ke dalam modul baru dengan kelas Jackson yang telah dipindahkan sebagai gantinya.
Nota
Membuat JAR gemuk dengan kelas Jackson yang direlokasi tidak menyelesaikan konflik versi dalam contoh ini - hanya memaksa satu versi Jackson yang berteduh.
Membuat JAR besar
Lingkungan seperti Databricks atau Apache Spark memiliki manajemen dependensi kustom dan menyediakan pustaka umum seperti Jackson. Untuk menghindari konflik dengan pustaka yang disediakan, Anda mungkin ingin membuat fat JAR yang berisi keseluruhan dependensi. Untuk informasi selengkapnya, lihat Apache Maven Shade Plugin. Dalam banyak kasus, merelokasi kelas Jackson (com.fasterxml.jackson
) mengurangi masalah. Terkadang lingkungan tersebut juga membawa versi Azure SDK mereka sendiri, sehingga Anda mungkin terdorong untuk merelokasi namespace com.azure
untuk mengatasi konflik versi.
Memahami versi dependensi yang kompatibel
Untuk informasi tentang dependensi yang spesifik dan versinya, lihat azure-core
di Maven Central Repository. Tabel berikut ini memperlihatkan beberapa pertimbangan umum:
Ketergantungan | Versi yang didukung |
---|---|
Jackson | 2.10.0 dan versi minor yang lebih baru kompatibel. Untuk informasi selengkapnya, lihat bagian Dukungan untuk beberapa versi Jackson . |
SLF4J | 1.7.* |
netty-tcnative-boringssl-static | 2.0.* |
netty-common | 4.1.* |
inti reaktor | 3.X.* - Nomor versi besar dan kecil harus sama persis dengan versi yang bergantung pada azure-core Anda. Untuk informasi selengkapnya, lihat kebijakan Reaktor Proyek tentang penghentian. |
Dukungan untuk beberapa versi Jackson
Azure SDK untuk Java mendukung bekerja dengan berbagai versi Jackson. Versi terendah yang didukung adalah Jackson 2.10.0. Pustaka klien Azure SDK for Java menyesuaikan konfigurasinya dan penggunaan Jackson tergantung pada versi yang terdeteksi saat runtime. Penyesuaian ini memungkinkan kompatibilitas yang lebih besar dengan versi kerangka kerja Spring yang lebih lama, Apache Spark, dan lingkungan umum lainnya. Aplikasi dapat menurunkan versi Jackson (ke 2.10.0 atau lebih tinggi) tanpa merusak Azure SDK untuk pustaka klien Java.
Nota
Menggunakan versi lama Jackson dapat mengekspos aplikasi terhadap kerentanan dan masalah yang diketahui. Untuk informasi selengkapnya, lihat daftar kerentanan yang diketahui untuk pustaka Jackson.
Saat menyematkan versi Jackson tertentu, pastikan untuk melakukannya untuk semua modul yang digunakan oleh Azure SDK, yang ditampilkan dalam daftar berikut:
jackson-annotations
jackson-core
jackson-databind
jackson-dataformat-xml
jackson-datatype-jsr310
Migrasi dari Jackson ke azure-json
Pustaka klien Azure untuk Java sedang dalam proses migrasi ke azure-json, yang tidak bergantung pada komponen pihak ke-3, dan menawarkan primitif, abstraksi, dan pembantu bersama untuk JSON.
Lingkungan seperti Apache Spark, Apache Flink, dan Databricks mungkin membawa versi azure-core
lama yang belum bergantung pada azure-json
. Akibatnya, saat menggunakan versi pustaka Azure yang lebih baru di lingkungan tersebut, Anda mungkin mendapatkan kesalahan yang mirip dengan java.lang.NoClassDefFoundError: com/azure/json/JsonSerializable
. Anda dapat mengurangi kesalahan ini dengan menambahkan dependensi eksplisit pada azure-json
.
Langkah selanjutnya
Setelah Anda terbiasa dengan konflik versi dependensi dan cara memecahkan masalahnya, lihat Manajemen Dependensi untuk Java untuk informasi tentang cara terbaik untuk mencegahnya.