Azure / azure-sdk-for-java

This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
MIT License
2.26k stars 1.94k forks source link

[BUG] Circular references about restTemplateBuilder #31497

Open sigiswald opened 1 year ago

sigiswald commented 1 year ago

Describe the bug A Spring Boot 2.7.4 application having dependencies on both spring-boot-starter-data-rest and spring-cloud-azure-starter-active-directory 4.4.0 fails to start due to circular references. Using spring-cloud-azure-starter-active-directory 4.3.0 works fine.

Exception or Stack Trace

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

   com.azure.spring.cloud.autoconfigure.aad.AadAuthenticationFilterAutoConfiguration
┌─────┐
|  restTemplateBuilder defined in class path resource [org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration.class]
↑     ↓
|  restTemplateBuilderConfigurer defined in class path resource [org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration.class]
↑     ↓
|  messageConverters defined in class path resource [org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration.class]
↑     ↓
|  jacksonHttpMessageConverter defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]
↑     ↓
|  linkCollector defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]
↑     ↓
|  selfLinkProvider defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]
↑     ↓
|  org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration
↑     ↓
|  org.springframework.security.config.annotation.web.configuration.OAuth2ClientConfiguration$OAuth2ClientWebMvcSecurityConfiguration
↑     ↓
|  com.azure.spring.cloud.autoconfigure.aad.configuration.AadOAuth2ClientConfiguration
└─────┘

Action:

Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

To Reproduce Create a new Spring Boot project at https://start.spring.io/ and select the following dependencies:

Then enable AAD in the application.yaml file:

spring:
  cloud:
    azure:
      active-directory:
        enabled: true
        credential:
          client-id: whatever
          client-secret: whatever
        profile:
          tenant-id: whatever
        user-group:
          allowed-group-names: whatever

Code Snippet N/A

Expected behavior The Spring Boot application starts (and immediately terminates because it's not a web application) without error.

Screenshots N/A

Setup (please complete the following information):

Additional context This could be related to https://github.com/Azure/azure-sdk-for-java/pull/31048 Downgrading to com.azure.spring:spring-cloud-azure-starter-active-directory:4.3.0 solves the problem. Removing the org.springframework.boot:spring-boot-starter-data-rest dependency also "solves" the problem.

Information Checklist Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report

chenrujun commented 1 year ago

Hi, @sigiswald, thanks for reaching out. I'll investigate this issue and give feedback ASAP.

chenrujun commented 1 year ago

Update:

I tried these 3 methods, but failed:

fangjian0423 commented 1 year ago

It seems the mvcConversionService bean used in RepositoryRestMvcConfiguration cause the circular reference problem.

mvcConversionService was constructed by WebMvcAutoConfiguration.

I did some tests to verify mvcConversionService cause circular dependency problem.

  1. Add spring-boot-starter-web dependency
  2. Delete spring-boot-starter-data-rest dependency
  3. Define custom HttpMessageConverter that dependency on mvcConversionService

Custom HttpMessageConverter:

public class MyMessageConverter implements HttpMessageConverter {

    private final ConversionService conversionService;

    public MyMessageConverter(ConversionService conversionService) {
        this.conversionService = conversionService;
    }
    ...
}

Configuration Class:

@Configuration
public class MyConfiguration {
    @Bean
    public HttpMessageConverter myConverter(
                                             @Qualifier("mvcConversionService") ObjectProvider<ConversionService> conversionService) {
        return new MyMessageConverter(conversionService.getIfAvailable());
    }
}

Stack Trace:

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

   com.azure.spring.cloud.autoconfigure.aad.AadAuthenticationFilterAutoConfiguration
┌─────┐
|  restTemplateBuilder defined in class path resource [org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration.class]
↑     ↓
|  restTemplateBuilderConfigurer defined in class path resource [org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration.class]
↑     ↓
|  messageConverters defined in class path resource [org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration.class]
↑     ↓
|  myConverter defined in class path resource [com/example/demo/MyConfiguration.class]
↑     ↓
|  org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration
↑     ↓
|  org.springframework.security.config.annotation.web.configuration.OAuth2ClientConfiguration$OAuth2ClientWebMvcSecurityConfiguration
↑     ↓
|  com.azure.spring.cloud.autoconfigure.aad.configuration.AadOAuth2ClientConfiguration
└─────┘
mnhock commented 1 year ago

There are any updates on this issue?

Downgrading to 4.3.0 works for us as well.

Thank you very much!

chenrujun commented 1 year ago

Hi, @mnhock

Thanks for reaching out. Actually, there is no updates in Spring Cloud Azure side. It's caused by spring-data-rest, if you are not using spring-data-rest, you will not face this problem. We already created an issue in spring-data-rest side: https://github.com/spring-projects/spring-data-rest/issues/2193

francisco-chaves-dc commented 1 year ago

Downgrading to 4.3.0 worked for me as well.

chenrujun commented 1 year ago

@francisco-chaves-dc

Thanks for sharing the information.

Here is the conclusion:

Workarounds

  1. Downgrading to 4.3.0
  2. Nos using Spring Cloud Azure and Spring Data Rest at the same time.
fangjian0423 commented 1 year ago

@saragluna could you please take a look at this issue, thanks.

tommyNy commented 1 year ago

@saragluna any info?

saragluna commented 1 year ago

@tommyNy sorry, but we are still trying to find a solution here.

end-user commented 1 year ago

Just discovered this issue myself; following.

thatapplefreak commented 10 months ago

Any update on this? I've encountered what I think is the same issue with Spring Boot 3.1.3 and Cloud Azure 5.5.0

***************************                                                                                                                                                                 
APPLICATION FAILED TO START                                                                                                                                                                 
***************************                                                                                                                                                                 

Description:                                                                                                                                                                                

The dependencies of some of the beans in the application context form a cycle:                                                                                                              

???????                                                                                                                                                                                     
|  org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration                                                                                     
?     ?                                                                                                                                                                                     
|  org.springframework.security.config.annotation.web.configuration.OAuth2ClientConfiguration$OAuth2ClientWebMvcSecurityConfiguration                                                       
?     ?                                                                                                                                                                                     
|  com.azure.spring.cloud.autoconfigure.implementation.aad.configuration.AadOAuth2ClientConfiguration                                                                                       
?     ?                                                                                                                                                                                     
|  restTemplateBuilder defined in class path resource [org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration.class]                                               
?     ?                                                                                                                                                                                     
|  restTemplateBuilderConfigurer defined in class path resource [org/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration.class]                                     
?     ?                                                                                                                                                                                     
|  messageConverters defined in class path resource [org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration.class]                                              
?     ?                                                                                                                                                                                     
|  jacksonHttpMessageConverter defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]                                            
?     ?                                                                                                                                                                                     
|  linkCollector defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]                                                          
?     ?                                                                                                                                                                                     
|  selfLinkProvider defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]                                                       
???????                                                                                                                                                                                     
pietervdheijden commented 9 months ago

I had exactly the same issue as @thatapplefreak. Downgrading to v4.3.0 worked for me.


Update: downgrading did not work... Also, the fix @yoranvanoirschot mentions in his comment did not work. Therefore, we ended up removing dependency spring-data-rest.

yoranvanoirschot commented 9 months ago

Downgrading to v4.3.0 was not an option for us since this was giving issues with the decryption of tokens of service principals. Instead, I created a simple workaround which you can easily embed in your project. The gist: https://gist.github.com/yoranvanoirschot/1b3c91df4f60b9d8522162fbee5ef4e3

Goodluck!

moarychan commented 9 months ago

Hi @yoranvanoirschot , thanks for your update! It seems that your solution cannot solve the circular dependency problem. Maybe I don't understand your solution. Could you give more specific instructions?

rtorregrosa commented 8 months ago

Downgrading to v4.3.0 was not an option for us since this was giving issues with the decryption of tokens of service principals. Instead, I created a simple workaround which you can easily embed in your project. The gist: https://gist.github.com/yoranvanoirschot/1b3c91df4f60b9d8522162fbee5ef4e3

Goodluck!

Hi @yoranvanoirschot, I am trying to implement your solution, but I see that FixAadB2cOAuth2ClientConfiguration class has the package "com.azure.spring.cloud.autoconfigure.implementation.aadb2c.configuration", how did you put that class inside the "spring-cloud-azure-autoconfigure" dependency jar?

On the other hand, has been any progress with this issue? Thanks!

harry12345678910 commented 5 months ago

Hi,

any progress with this issue? Also hit the wall.

Thanks.

Netyyyy commented 5 months ago

Hi, @harry12345678910 , sorry but we will continue to look for a possible solution.