Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Circular Dependency Issue - V2.6 to Latest #36286

Closed
zpreston123 opened this issue Jul 9, 2023 · 9 comments
Closed

Circular Dependency Issue - V2.6 to Latest #36286

zpreston123 opened this issue Jul 9, 2023 · 9 comments
Labels
status: invalid An issue that we don't feel is valid

Comments

@zpreston123
Copy link

zpreston123 commented Jul 9, 2023

Having an issue resolving circular dependency in a Spring Boot Starter project (version 3.1) with Gradle.

Using setter injection with @Autowired annotation.

After building the project, the following output displayed:

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-07-09T16:45:14.463-04:00 ERROR 3398 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

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

Description:

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

┌─────┐
|  classA
↑     ↓
|  classB
└─────┘


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.

*Note: Project ran successfully with an older Spring Boot version (2.5.15).
Also tested it using 2.6.0 - same issue occurred.

Appears to be an issue with versions 2.6 and above.

Application code below:

MainApp.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MainApp {
    public static void main(String[] args) {
        SpringApplication.run(MainApp.class);
    }
}

ClassA.java

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ClassA {
    private ClassB classB;

    @Autowired
    public void setClassB(ClassB classB) {
        this.classB = classB;
    }
}

ClassB.java

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ClassB {
    private ClassA classA;

    @Autowired
    public void setClassA(ClassA classA) {
        this.classA = classA;
    }
}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jul 9, 2023
@zpreston123 zpreston123 changed the title Circular Dependencies Issue Cannot Resolve Circular Dependency Issue Jul 9, 2023
@zpreston123 zpreston123 changed the title Cannot Resolve Circular Dependency Issue Circular Dependency Issue - V2.6 to Latest Jul 9, 2023
@philwebb
Copy link
Member

philwebb commented Jul 9, 2023

Please see this section of the 2.6 release notes.

@philwebb philwebb closed this as not planned Won't fix, can't repro, duplicate, stale Jul 9, 2023
@philwebb philwebb added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged labels Jul 9, 2023
@zpreston123
Copy link
Author

zpreston123 commented Jul 10, 2023

@philwebb Reviewed the Circular Dependencies section and am aware of the applications.properties file workaround (not recommended).

There should not be a cyclic dependency after using one of the resolution methods.

In this example, setter injection is used.

See code above.

@snicoll
Copy link
Member

snicoll commented Jul 10, 2023

There should not be a cyclic dependency after using one of the resolution methods.

What resolution method are you talking about? A depends on B and B depends on A so, conceptually, there is clearly a cycle. It looks like you believe that setter injection should fix the cycle. Can you expand on that?

@zpreston123
Copy link
Author

@snicoll Setter injection using "@Autowired" annotation.

See https://www.baeldung.com/circular-dependencies-in-spring#3-use-setterfield-injection for more information.

@bclozel
Copy link
Member

bclozel commented Jul 10, 2023

@zpreston123

  1. The Workarounds

This article lists workarounds to make things work despite the circular dependency, but it doesn't fix the circular dependency itself. @snicoll 's comment still stands and so does the release notes. If you believe this article is misleading, please reach out to the authors.

@zpreston123
Copy link
Author

@bclozel This is one of the common methods to resolve the circular dependency issue.

Also mentioned in the Spring documentation (https://docs.spring.io/spring-framework/reference/core/beans/dependencies/factory-collaborators.html#beans-dependency-resolution).

This method should prevent Spring from injecting the dependencies while the objects are created during context loading.

Any suggestions?

@wilkinsona
Copy link
Member

It doesn't resolve a circular dependency issue. It's still very much there, just slightly hidden. You should either refactor your code (recommended) or set spring.main.allow-circular-references=true.

@zpreston123
Copy link
Author

zpreston123 commented Jul 11, 2023

@wilkinsona Code provided is a simple example - refactoring is not necessary.

Setting spring.main.allow-circular-references=true is not recommended.

Using setter injection as one of the resolution methods specified in the Spring documentation should not throw an exception.

See exception details below:

2023-07-11T09:43:27.609-04:00  WARN 8992 --- [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'classA': Unsatisfied dependency expressed through method 'setClassB' parameter 0: Error creating bean with name 'classB': Unsatisfied dependency expressed through method 'setClassA' parameter 0: Error creating bean with name 'classA': Requested bean is currently in creation: Is there an unresolvable circular reference?

@wilkinsona
Copy link
Member

Setting spring.main.allow-circular-references=true is not recommended.

It isn't recommended as we believe that refactoring your code to remove circular dependencies of any form is a better approach.

Using setter injection as one of the resolution methods specified in the Spring documentation should not throw an exception.

Then please set the property. That's what it's there for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

6 participants