다음을 통해 공유


종속성 버전 충돌 문제 해결

이 문서에서는 종속성 버전 충돌과 이를 해결하는 방법을 설명합니다.

Java용 Azure 클라이언트 라이브러리는 다음과 같은 인기 있는 타사 라이브러리에 따라 달라집니다.

많은 Java 애플리케이션 및 프레임워크는 이러한 라이브러리를 직접 또는 전이적으로 사용하며, 이로 인해 버전 충돌이 발생합니다. MavenGradle과 같은 종속성 관리자는 클래스 경로에 대한 각 종속성의 단일 버전만 있도록 모든 종속성을 확인합니다. 그러나 확인된 종속성 버전이 애플리케이션에서 해당 종속성의 모든 소비자와 호환된다는 보장은 없습니다. 자세한 내용은 Maven 설명서의 종속성 메커니즘 소개 및 Gradle 설명서의 종속성 확인 이해를 참조하세요.

직접 의존성의 API 비호환성으로 인해 컴파일 오류가 발생합니다. 다이아몬드 종속성 비호환성으로 인해 일반적으로 NoClassDefFoundError, NoSuchMethodError 또는 기타 LinkageError와 같은 런타임 오류가 발생합니다. 모든 라이브러리가 의미 체계 버전 지정을 엄격하게 따르지는 않으며, 종종 동일한 주 버전 내에서 주요 변경 내용이 발생합니다.

버전 불일치 문제 진단

다음 섹션에서는 버전 불일치 문제를 진단하는 방법에 대한 방법을 설명합니다.

Java용 Azure SDK 빌드 도구 사용

Azure SDK 및 Apache Maven 시작에 도입된 Java용 Azure SDK 빌드 도구는 일반적으로 발생하는 문제를 식별하는 데 도움이 됩니다. 이 빌드 도구를 프로젝트에 추가하고 Maven 대상을 일반 빌드 프로세스에 추가하여 azure:run 실행하는 것이 좋습니다. 적절한 구성을 사용하면 런타임에 문제가 되기 전에 종속성 충돌을 보다 사전에 식별하고 해결할 수 있습니다.

종속성 트리 보기

mvn dependency:tree 또는 gradle dependencies --scan을 실행하여 버전 번호가 있는 애플리케이션에 대한 전체 종속성 트리를 표시합니다. mvn dependency:tree -Dverbose 는 자세한 정보를 제공하지만 오해의 소지가 있을 수 있습니다. 자세한 내용은 Maven 설명서의 Apache Maven 종속성 트리 를 참조하세요. 버전 충돌이 있는 것으로 의심되는 각 라이브러리에 대해 버전 번호를 적어 두고 해당 버전에 의존하는 구성 요소를 결정합니다.

개발 및 프로덕션 환경의 종속성 확인은 다르게 작동할 수 있습니다. Apache Spark, Apache Flink, Databricks 및 IDE 플러그 인에는 사용자 지정 종속성을 위한 추가 구성이 필요합니다. 또한 자체 버전의 Azure 클라이언트 라이브러리 또는 공통 구성 요소를 가져올 수도 있습니다. 자세한 내용은 다음 문서를 참조하세요.

이러한 환경에서 충돌 해결에 대한 자세한 내용은 이 문서의 후반부에 있는 fat JAR 만들기 섹션을 참조하세요.

Azure Functions 구성

Azure Functions의 내부 종속성 버전(Java 8만 실행)이 사용자가 제공한 버전보다 우선합니다. 이 종속성으로 인해 특히 Jackson, Netty 및 Reactor에서 버전 충돌이 발생합니다.

이 문제를 해결하려면 FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS 환경 변수를 true 또는 1로 설정합니다. Azure Function Tools(v2 또는 v3)를 최신 버전으로 업데이트해야 합니다.

참고 항목

이 구성은 Java 8만 실행하는 Azure Functions에 적용되며, Java 11을 실행하는 Functions에는 특별한 구성이 필요하지 않습니다.

Apache Spark 구성

Java용 Azure SDK는 여러 버전의 Jackson을 지원하지만 빌드 도구 및 종속성 확인 순서에 따라 문제가 발생할 수 있습니다. 이 문제의 좋은 예는 Jackson 2.10에 따라 달라지는 Apache Spark 버전 3.0.0 이상입니다. Java용 Azure SDK와 호환되지만 개발자는 최신 버전의 Jackson이 대신 사용되므로 비호환성이 발생하는 경우가 많습니다. 이 문제를 완화하려면 특정 버전의 Jackson(Spark와 호환되는 버전)을 고정해야 합니다. 자세한 내용은 이 문서의 여러 Jackson 버전 지원 섹션을 참조하세요.

이전 버전의 Spark를 사용하거나 사용하는 다른 라이브러리에 Java용 Azure SDK가 지원하지 않는 이전 버전의 Jackson이 필요한 경우 가능한 완화 단계를 위해 이 문서를 계속 읽으세요.

Jackson 런타임 버전 검색

Azure Core 1.21.0에서는 Jackson 런타임 버전의 런타임 검색 및 더 나은 진단 기능을 추가했습니다.

Jackson API와 관련된 LinkageError(또는 해당 서브클래스)가 표시되면 예외 메시지에서 런타임 버전 정보를 확인합니다. 예: 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경고 및 오류 로그를 찾습니다. 자세한 내용은 Java용 Azure SDK의 로깅 구성을 참조하세요. 예: [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 버전은 알려진 취약성 및 문제에 애플리케이션을 노출할 수 있으므로 다운그레이드하지 마세요.

셰이드 라이브러리

경우에 따라 함께 작동하는 라이브러리 조합이 없으며 음영이 최후의 수단으로 제공됩니다.

참고 항목

음영은 클래스 경로에서 패키지 크기 및 클래스 수를 늘리고, 코드 탐색 및 디버깅을 어렵게 만들고, JNI 코드를 재배치하지 않고, 리플렉션을 중단하며, 코드 라이선스를 위반할 수 있다는 상당한 단점이 있습니다. 다른 옵션을 모두 사용한 후에만 사용해야 합니다.

음영을 사용하면 빌드 시 JAR 내에 종속성을 포함하고 패키지 이름을 바꾸고 애플리케이션 코드를 업데이트하여 음영 처리된 위치에서 코드를 사용할 수 있습니다. 종속성의 서로 다른 복사본이 두 개 있으므로 다이아몬드 종속성 충돌은 더 이상 문제가 되지 않습니다. 다음 목록에 설명된 대로 충돌하는 전이적 종속성 또는 직접 애플리케이션 종속성이 있는 라이브러리를 음영 처리할 수 있습니다.

  • 전이적 종속성 충돌: 예를 들어 타사 라이브러리 A 에는 Azure SDK가 지원하지 않는 Jackson 2.9가 필요하며 업데이트 A할 수 없습니다. A 및 음영(재배치) Jackson 2.9와 필요에 따라 A의 다른 종속성도 포함하는 새 모듈을 만듭니다.
  • 애플리케이션 종속성 충돌: 애플리케이션에서 Jackson 2.9를 직접 사용합니다. 코드를 업데이트하는 동안 잭슨 2.9를 재배치된 Jackson 클래스가 있는 새 모듈로 음영 처리하고 재배치할 수 있습니다.

참고 항목

재배치된 Jackson 클래스를 통해 fat JAR을 만들면 이러한 예제에서 버전 충돌이 해결되지 않습니다. 즉, Jackson의 단일 음영 처리된 버전만 강제합니다.

fat JAR 만들기

Databricks 또는 Apache Spark와 같은 환경에는 사용자 지정 종속성 관리가 있으며, Jackson과 같은 일반적인 라이브러리를 제공합니다. 제공된 라이브러리와의 충돌을 방지하려면 모든 종속성을 포함하는 fat JAR을 빌드하면 됩니다. 자세한 내용은 Apache Maven Shade 플러그 인을 참조하세요. 대부분의 경우 Jackson 클래스(com.fasterxml.jackson)를 재배치하면 문제가 완화됩니다. 경우에 따라 이러한 환경은 자체 버전의 Azure SDK를 가져오므로 버전 충돌을 해결하기 위해 com.azure 네임스페이스를 재배치해야 할 수도 있습니다.

호환되는 종속성 버전 이해

특정 종속성 및 해당 버전에 대한 azure-core자세한 내용은 Maven 중앙 리포지토리의 azure-core를 참조하세요. 다음 표에서는 몇 가지 일반적인 고려 사항을 보여줍니다.

Dependency 지원되는 버전
Jackson 2.10.0 이상 부 버전이 호환됩니다. 자세한 내용은 여러 Jackson 버전 지원 섹션을 참조하세요.
SLF4J 1.7.*
netty-tcnative-boringssl-static 2.0.*
netty-common 4.1.*
reactor-core 3.X.* - 주 버전 및 부 버전 번호는 azure-core 버전이 사용하는 번호와 정확히 일치해야 합니다. 자세한 내용은 Project Reactor 사용 중단 정책을 참조하세요.

여러 Jackson 버전 지원

Java용 Azure SDK는 다양한 Jackson 버전 작업을 지원합니다. 가장 낮은 지원 버전은 Jackson 2.10.0입니다. Java용 Azure SDK 클라이언트 라이브러리는 런타임에 검색된 버전에 따라 구성 및 Jackson 사용량을 조정합니다. 이렇게 조정하면 이전 버전의 Spring Framework, Apache Spark 및 기타 일반 환경과의 호환성이 향상됩니다. 애플리케이션은 Java용 Azure SDK 클라이언트 라이브러리를 중단하지 않고 Jackson 버전을 2.10.0 이상으로 다운그레이드할 수 있습니다.

참고 항목

이전 버전의 Jackson을 사용하면 애플리케이션을 알려진 취약성 및 문제에 노출할 수 있습니다. 자세한 내용은 Jackson 라이브러리의 알려진 취약성 목록을 참조하세요.

특정 버전의 Jackson을 고정할 때 다음 목록에 표시된 Azure SDK에서 사용하는 모든 모듈에 대해 이 작업을 수행해야 합니다.

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

Jackson에서 azure-json으로 마이그레이션

Java용 Azure 클라이언트 라이브러리는 타사 구성 요소에 의존하지 않고 JSON에 대한 공유 기본 형식, 추상화 및 도우미를 제공하는 azure-json으로 마이그레이션하는 중입니다.

Apache Spark, Apache Flink 및 Databricks와 같은 환경에서는 아직 의존azure-json하지 않는 이전 버전을 azure-core 가져올 수 있습니다. 따라서 이러한 환경에서 최신 버전의 Azure 라이브러리를 사용하는 경우 다음과 유사한 java.lang.NoClassDefFoundError: com/azure/json/JsonSerializable오류가 발생할 수 있습니다. 에 대한 명시적 종속성을 추가하여 이 오류를 완화할 수 있습니다 azure-json.

다음 단계

종속성 버전 충돌 및 문제를 해결하는 방법에 익숙해졌으므로 이를 방지하는 가장 좋은 방법에 대한 정보는 Java용 종속성 관리를 참조하세요.