共用方式為


針對相依性版本衝突進行疑難解答

本文說明相依性版本衝突,以及如何進行疑難解答。

適用於 Java 的 Azure 用戶端連結庫取決於熱門的第三方連結庫,例如下列連結庫:

許多 Java 應用程式和架構會直接或可轉移地使用這些連結庫,這會導致 版本衝突。 MavenGradle 等相依性管理員會解析所有相依性,因此類別路徑上只有單一版本的每個相依性。 不過,不保證解析的相依性版本與應用程式中該相依性的所有取用者相容。 如需詳細資訊,請參閱 Maven 檔中的相依性機制 簡介和 Gradle 檔中的瞭解相依性解析

直接相依性的 API 不相容會導致編譯錯誤。 鑽石相依性不相容通常會導致運行時間失敗,例如 NoClassDefFoundErrorNoSuchMethodError 或其他 LinkageError。 並非所有連結庫都嚴格遵循 語意版本控制,而中斷性變更有時會在相同的主要版本中發生。

診斷版本不符問題

下列各節說明如何診斷版本不符問題的方法。

使用 Azure SDK for Java 建置工具

開始使用 Azure SDK 和 Apache Maven引進的 Azure SDK for Java 建置工具可協助識別常見問題。 建議您將此建置工具新增至專案,並將 Maven 目標新增 azure:run 至您的一般建置程式來執行它。 使用適當的設定,您可以更主動地識別並解決相依性衝突,再於運行時間發生問題。

檢視相依性樹狀結構

執行 mvn dependency:treegradle dependencies --scan 顯示應用程式的完整相依性樹狀結構,版本號碼。 mvn dependency:tree -Dverbose 提供詳細資訊,但可能會產生誤導。 如需詳細資訊,請參閱 Maven 檔中的 Apache Maven 相依性樹 狀結構。 針對您懷疑的每個連結庫都有版本衝突,請注意其版本號碼,並判斷哪些元件相依於它。

開發和生產環境中的相依性解析可能會有不同的運作方式。 Apache SparkApache FlinkDatabricks 和 IDE 外掛程式需要額外的自定義相依性設定。 他們也可以攜帶自己的 Azure 用戶端連結庫或通用元件版本。 如需詳細資訊,請參閱下列文章:

如需這類環境中衝突解決的詳細資訊,請參閱 本文稍後的<建立胖 JAR >一節。

設定 Azure Functions

Azure Functions 上的內部相依性版本(僅限執行 Java 8)的優先順序高於使用者提供的相依性版本。 此相依性會導致版本衝突,特別是傑克遜、Netty 和 Reactor。

若要解決此問題,請將 FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS 環境變數設定為 true1。 請務必將 Azure 函式工具 (v2 或 v3) 更新為最新版本。

注意

此設定僅適用於執行 Java 8 的 Azure Functions,執行 Java 11 的 Functions 不需要特殊設定。

設定 Apache Spark

適用於 Java 的 Azure SDK 支援多個版本的 Jackson,但有時可能會根據您的建置工具及其相依性解析順序而發生問題。 此問題的一個很好的範例是 Apache Spark 3.0.0 版和更新版本,這相依於 Jackson 2.10。 雖然它與適用於 Java 的 Azure SDK 相容,但開發人員通常會發現會改用較新版本的 Jackson,這會導致不相容。 若要解決此問題,您應該釘選特定版本的 Jackson (與 Spark 相容版本)。 如需詳細資訊,請參閱 本文中的<支援多個 Jackson 版本 >一節。

如果您使用舊版 Spark,或者,如果您使用的另一個連結庫需要舊版的 Jackson,則 Azure SDK for Java 不支援,請繼續閱讀本文,以取得可能的緩和步驟。

偵測 Jackson 執行時間版本

在 Azure Core 1.21.0 中,我們新增了傑克遜運行時間版本的運行時間偵測和更好的診斷。

如果您看到 LinkageError 與 Jackson API 相關的任何子類別,請檢查例外狀況的訊息以瞭解運行時間版本資訊。 例如: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

尋找 來自 JacksonVersion的警告和錯誤記錄檔。 如需詳細資訊,請參閱 在 Azure SDK for Java 中設定記錄。 例如:[main] ERROR com.azure.core.implementation.jackson.JacksonVersion - Version '2.9.0' of package 'jackson-core' is not supported (too old), please upgrade.

注意

檢查所有 Jackson 套件都有相同的版本。

如需 Azure SDK 和支援的 Jackson 版本所使用的套件清單,請參閱 支援多個 Jackson 版本 一節。

減輕版本不符的問題

下列各節說明如何減輕版本不符的問題。

使用 Azure SDK BOM

使用最新的穩定 Azure SDK BOM ,且不會在 POM 檔案中指定 Azure SDK 和相依性版本。 適用時,請使用 Azure Spring Boot BOM

Azure SDK BOM 中列出的相依性會經過嚴格測試,以避免相依性衝突。

避免不必要的相依性

如果可以,請移除相依性。 有時候,應用程式相依於多個連結庫,基本上提供相同的功能。 這類不必要的相依性會將應用程式公開至安全性弱點、版本衝突,以及支援和維護成本。

更新相依性版本

如果切換至最新的 Azure SDK BOM 沒有説明,請識別造成衝突的連結庫,以及使用這些連結庫的元件。 (如需詳細資訊,請參閱 請檢視本文稍早的相依性樹狀結構 一節。嘗試更新至較新版本,以防範安全性弱點,而且通常會帶來新功能、效能改善和錯誤修正。

避免降級 Azure SDK 版本,因為它可能會讓您的應用程式暴露在已知的弱點和問題。

陰影庫

有時候沒有連結庫組合在一起,陰影是最後的手段。

注意

底紋有顯著的缺點:它會增加 classpath 上的套件大小和類別數目,讓程式代碼瀏覽和偵錯變得難以進行,不會重新放置 JNI 程式代碼、中斷反映,而且可能會違反程式代碼授權等。 只有在其他選項用盡之後,才應該使用它。

底紋可讓您在建置階段在 JAR 中包含相依性,然後重新命名套件並更新應用程式程式代碼,以使用陰影位置中的程式代碼。 鑽石相依性衝突不再是問題,因為相依性有兩個不同的復本。 您可以著色具有衝突的可轉移相依性或直接應用程式相依性的連結庫,如下列清單所述:

  • 可轉移的相依性衝突:例如,第三方連結庫 A 需要 Jackson 2.9,Azure SDK 不支援,而且無法更新 A。 建立新的模組,其中包含 A 和陰影 (重新放置) Jackson 2.9,並選擇性地包含和 的其他相 A依性。
  • 應用程式相依性衝突:您的應用程式會直接使用Jackson 2.9。 當您在更新程序代碼時,可以改為將 Jackson 2.9 著色並重新放置到具有已重新置放的 Jackson 類別的新課程模組中。

注意

使用重新置放的 Jackson 類別來建立胖 JAR 並不會解決這些範例中的版本衝突, 它只會強制使用單一陰影版本的 Jackson。

建立胖 JAR

Databricks 或 Apache Spark 等環境具有自定義相依性管理,並提供像 Jackson 這樣的通用連結庫。 若要避免與所提供的連結庫發生衝突,您可能想要建置包含所有相依性的胖 JAR。 如需詳細資訊,請參閱 Apache Maven 著色外掛程式。 在許多情況下,重新放置 Jackson 類別(com.fasterxml.jackson) 可減輕此問題。 有時候這類環境也會攜帶自己的 Azure SDK 版本,因此您可能被迫重新配置 com.azure 命名空間,以解決版本衝突。

瞭解相容的相依性版本

如需特定相依性及其版本的相關信息 azure-core,請參閱 Maven 中央存放庫中的 azure-core 。 下表顯示一些一般考慮:

Dependency 支援的版本
傑克遜 2.10.0 和較新的次要版本相容。 如需詳細資訊,請參閱 支援多個 Jackson 版本 一節。
SLF4J 1.7.*
netty-tcnative-boringssl-static 2.0.*
netty-common 4.1.*
reactor-core 3.X.* - 主要和次要版本號碼必須完全符合您 azure-core 版本相依的版本。 如需詳細資訊,請參閱關於取代的項目反應堆原則。

支援多個 Jackson 版本

適用於 Java 的 Azure SDK 支援使用一系列 Jackson 版本。 最低支援的版本是 Jackson 2.10.0。 Azure SDK for Java 用戶端連結庫會根據運行時間偵測到的版本來調整其設定和 Jackson 使用量。 這項調整可讓您與舊版 Spring 架構、Apache Spark 和其他常見環境產生更大的相容性。 應用程式可以降級 Jackson 版本(至 2.10.0 或更高版本),而不會中斷適用於 Java 用戶端連結庫的 Azure SDK。

注意

使用舊版的 Jackson 可能會讓應用程式暴露在已知的弱點和問題。 如需詳細資訊,請參閱 Jackson 連結庫的已知弱點清單。

釘選特定版本的 Jackson 時,請務必針對 Azure SDK 所使用的所有模組執行此動作,如下列清單所示:

  • jackson-annotations
  • jackson-core
  • jackson-databind
  • jackson-dataformat-xml
  • jackson-datatype-jsr310

從 Jackson 移轉至 azure-json

適用於 Java 的 Azure 用戶端連結庫正在移轉至 azure-json,這並不相依於任何第三方元件,並提供 JSON 的共用基本類型、抽象概念和協助程式。

Apache Spark、Apache Flink 和 Databricks 等環境可能會帶來尚未相依azure-json的較舊版本azure-core。 因此,在這類環境中使用較新版本的 Azure 連結庫時,您可能會收到類似 java.lang.NoClassDefFoundError: com/azure/json/JsonSerializable的錯誤。 您可以藉由在 上 azure-json新增明確的相依性來減輕此錯誤。

下一步

既然您已熟悉相依性版本衝突以及如何進行疑難解答,請參閱 Java 的相依性管理,以取得防止其最佳方式的資訊。