microsoft / spring-cloud-azure

Spring Cloud Azure is an open-source project that provides seamless Spring integration with Azure services.
https://microsoft.github.io/spring-cloud-azure
MIT License
217 stars 105 forks source link

[BUG] Java dependency conflicts when use spring-cloud-azure-starter-keyvault-secrets in Spring Boot 3 #1053

Closed seyiayeni closed 1 year ago

seyiayeni commented 1 year ago

I am getting the following NoSuchMethodError error while using version 5.0.0 of the keyvault-secrets package. implementation 'com.azure.spring:spring-cloud-azure-starter-keyvault-secrets:5.0.0' in spring boot 3.0.4 and Java 17.

java.lang.NoSuchMethodError: 'reactor.core.publisher.Mono reactor.core.publisher.Mono.subscriberContext()'

Seems the subscriberContext was removed in rector 3.5 which spring boot 3 now uses and spring-cloud-azure still uses the old version of reactor

Will there be support for support for Spring boot 3 anytime soon?

chenrujun commented 1 year ago

Hi, @seyiayeni

Thanks for reaching out. spring-cloud-azure-starter-keyvault-secrets:5.0.0 should support Spring Boot 3 well. spring-cloud-azure-starter-keyvault-secrets:5.0.0 depends on reactor-core:3.5.3. Here is the screenshot of my build.gradle and dependency tree:

image

I think the following error is not caused by spring-cloud-azure-starter-keyvault-secrets:5.0.0.

java.lang.NoSuchMethodError: 'reactor.core.publisher.Mono reactor.core.publisher.Mono.subscriberContext()'

Could you please share your build.gradle file?

seyiayeni commented 1 year ago

Hello @chenrujun

Here is the content of my build.gradle file

` plugins { id 'java' id 'org.springframework.boot' version '3.0.4' id 'io.spring.dependency-management' version '1.1.0' }

group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17'

repositories { mavenCentral() }

dependencies { annotationProcessor "org.projectlombok:lombok:1.18.24" annotationProcessor "org.mapstruct:mapstruct-processor:1.18.24" annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0" implementation "org.projectlombok:lombok:1.18.24" implementation "org.apache.commons:commons-lang3:3.11" implementation 'org.springframework.boot:spring-boot-starter-webflux' implementation 'org.springframework.boot:spring-boot-starter-security' implementation "org.springframework.boot:spring-boot-starter-webflux" implementation "org.springframework.boot:spring-boot-starter-actuator" implementation "org.springframework.boot:spring-boot-starter-validation" implementation "com.azure.spring:spring-cloud-azure-starter-keyvault-secrets:5.0.0" testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' }

tasks.named('test') { useJUnitPlatform() } `

But I also noticed when I checked the dependencies tree, the spring-cloud-azure is pulling in reactor 3.4.23

Screenshot 2023-03-14 at 8 30 03 AM
chenrujun commented 1 year ago

Hi, @seyiayeni Thanks for your feedback.

Hi, @stliu, please take a look at this.

1. Root Cause Analysis

Dependency relationship between Spring Boot & Spring Cloud Azure & Azure SDK for Java & 3rd party dependency (take Reactor as an example):

image

source of above image

  1. Spring Cloud Azure has 2 major versions for different Spring Boot version.
    • Spring Cloud Azure:4.x compatible for Spring Boot:2.x.
    • Spring Cloud Azure:5.x compatible for Spring Boot:3.x.
  2. There is only one Azure SDK for Java. It doesn't compatible with both Spring Boot:2.x and Spring Boot:3.x.
    • If Azure SDK for Java choose option 1 in above picture, it cannot be compatible with Spring Boot:3.x. Currently, this option is chosen.
    • If Azure SDK for Java choose option 2 in above picture, it cannot be compatible with Spring Boot:2.x.

2. Solution proposal

2.1. Solution 1: Release 2 versions of Azure SDK for Java

Just like Spring Cloud Azure, release 2 versions of Azure SDK for Java. But it will cost a lot of effort. I don't prefer this option. The diagram will change to this:

image

source of above image

2.2. Solution 2: Make sure Azure SDK for Java compatible with both Spring Boot 2 and Spring Boot 3.

Make sure Azure SDK for Java just use the common part of Reactor 3.4 and Reactor 3.5.

The diagram will change to this:

image

source of above image

2.2.1. How to implement Solution 2

  1. Make all 3rd party dependencies'' versions align with spring-boot-dependencies:2.x. (We already finished this).
  2. Create routine job to create draft PR to update all 3rd party dependencies' versions according to spring-boot-dependencies: 3.x.
  3. Run all tests in the created draft PR.
    • Every artifact's unit tests.
    • Every artifact's integration tests.
  4. (Optional) To make the main branch always use the latest version of 3rd party dependencies, we can make main branch's 3rd party dependencies align with spring-boot-dependencies:3.x. And run tests for spring-boot-dependencies:2.x
saragluna commented 1 year ago

We have chosen to use the same sdk bom for Spring Boot 2.x and 3.x, and Spring Cloud Azure has released 5.4.0. Closing this issue now. Please reopen it if you are still facing this issu.e