István pató opened SPR-14307 and commented
https://github.com/spring-projects/spring-boot/issues/6045
We have an issue with 'circular reference' error. When I started my Spring Boot app on my Ubuntu 16.04 desktop OS, the issue is not showing up. If I running the app on the Ubuntu 16.10 Server OS, then I get an error:
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'exampleService': Requested bean is currently in creation: Is there an unresolvable circular reference?
If I change
@ComponentScan(basePackages = "org.springframework.boot.issues.ghXXXX")
to
@ComponentScan(basePackages = {"org.springframework.boot.issues.ghXXXX.server", "org.springframework.boot.issues.ghXXXX.service", "org.springframework.boot.issues.ghXXXX"})
then I don't get BeanCurrentlyInCreationException on Ubuntu 16.10 Server OS.
I can reproduce the issue with a maven project. The code is failing on same OS, if I change @ComponentScan
basePackages order.
Affects: 4.2.6
Reference URL: https://github.com/patoi/spring-boot-issues/tree/gh-6045/gh-6045
3 votes, 6 watchers
Comment From: spring-projects-issues
Juergen Hoeller commented
This is probably not related to the component scan order per se but rather to the initialization order of the beans contained in your packages: When ".server" gets picked up first, the beans in that package will get registered first and therefore initialized first, with a potential circular reference approached from that angle. Circular references are not cleanly resolvable from any side; depending on FactoryBean
setups or other indirections, they may fail from one end but not from the other. In that sense, the behavior that you're seeing is unfortunate but within our expectations for such an arrangement.
I'd rather get rid of the circular reference altogether. If that's not feasible, you could mark one or both dependency declarations as @Lazy
, allowing the container to postpone the initialization to their first actual use: This usually makes circular reference issues go away, since such circles are only really a problem if both ends of the dependency insist on getting a fully initialized other...
Alternatively, a depends-on
/ @DependsOn
declaration on your ".service" bean, pointing to the ".server" bean, expresses an explicit initialization order independent from the registration order. This would allow for always initializating your circular dependency from the same end, without any @Lazy
markers involved.
Comment From: spring-projects-issues
István pató commented
Thank you for answer!
Comment From: spring-projects-issues
Bulk closing outdated, unresolved issues. Please, reopen if still relevant.
Comment From: darssy
I'm afraid that this is still a reality.
I had that problem and I was fighting with it for the past 3 days. In my case it was something more weird. I was developing and running from IntelliJ. Everything was fine there. When I deployed the software to another machine resembling the production environment, I got a circular dependency error. After lots of trial and error I realized what the difference was: intelliJ relies on the class files to run the application. We were making a jar. After I set IntelliJ to create a jar and run the jar on my machine I got the same error.
I was able to fix it with the workaround mentioned here. There is still the concern though why this thing happens. I enabled debugging for spring, and I saw that the Eagerly caching bean 'XYZ' to allow for resolving potential circular references
messages were not appearing with the same order (comparing the classes vs jar execution). I also saw 45 less messages (compared to 144 that I was expecting to see). Again the only difference is the classes vs jar. The code is the same. This puzzles me as there shouldn't(?) be any differences between the 2 execution methods.
So the questions are: - Shouldn't the bean processing from Spring be deterministic? If not how can we make it? - Could that be a timing issue? Should we expect differences across different hardware and OSes? - Is there a difference between running spring applications from a jar versus from the class files? I searched but I couldn't find any difference.
I am at your disposal to provide any additional information as my team is very keen on having that resolved. The "random" manner of bean processing makes neither my teammates nor our managers confident. :(
Comment From: rstoyanchev
I was able to fix it with the workaround mentioned here.
Those are suggestions to improve the configuration to eliminate ambiguity, not workarounds.
Comment From: darssy
@rstoyanchev No disrespect: is this the only thing that stroke you odd? How about the randomness of processing the beans? And when I run the same application from IntelliJ there doesn't seem to be any ambiguity, everything there is crystal clear to spring...
Comment From: rstoyanchev
No offense taken. It's just that you've asked to re-open an old ticket that has the same Exception, but likely comes from very different context and maybe a different problem.
Comment From: darssy
OK then. If you want me to create a new ticked I will do so. I saw it being bulk closed with the note:
Bulk closing outdated, unresolved issues. Please, reopen if still relevant.
Emphasis is mine. I thought that it is unresolved and as such I is subject to reopening.
but likely comes from very different context and maybe a different problem.
Perhaps, perhaps not. That's why the issue is unresolved... All references to "occasional circular dependencies" were leading me to this issue. In any case if you think that it's better, I will be happy to create a new issue and copy all the information there.
Comment From: askerkhakh
Agreed with @adamstyl, this is very annoying, when circular dependencies error occurs randomly only on CI/CD stand.
Comment From: krasnyt
Still happening, 2.1.4.RELEASE.
Comment From: Arsennikum
Temporary crutch solution: ENV spring.main.lazy-initialization=true
Comment From: liaoke0123
@adamstyl there is a same case as you. When i run my spring project in DEV/QA environment or just run it in local side ( all of them run in wildfly server - that is Jboss) , ok there is no any probelm.
But if i run it in docker container for wildfly, there are a lot of circle dependences error messages pop up..
Comment From: liaoke0123
Temporary crutch solution:
ENV spring.main.lazy-initialization=true
@Arsennikum thx for u adding, but if i want to add this to normal spring project (not spring-boot), what can i do for this? BTW, which spring version can be supported?
Comment From: JanecekPetr
Now this happened to me. I thought I was smart when I tried to decorate a bean for tests like this:
/** the actual class used for prod */
@Service
public class ActualService {
// ...
}
// then in tests:
@Configuration
@ComponentScan(basePackages = {"com.company.package.blabla"})
@Import(ProdConfiguration.class)
public class TestConfiguration {
@Primary // override the default ActualService bean
@Bean
public ActualService fakeActualService(@Named("actualService") ActualService actualService) {
ActualService spy = Mockito.spy(actualService);
// do stuff with spy...
return spy;
}
}
the intent, for the particular test package, is to take the actual implementation and stub out some methods with fakes. Is this a bad design? Yes, welcome to legacy codebases. Please do not suggest how to fix this in an OO-friendly way, I know that and will do the refactoring as soon as possible.
That said, this works on Windows. It does not on Linux, with either BeanCurrentlyInCreationException
or NoSuchBeanDefinitionException
depending on the exact strategy (I tried with no @Named
first, but also with @DependsOn
, with adding a name to the original @Service
etc., no luck so far).
I understand my idea is probably wrong and only works by accident, but that's the point - if it works locally I totally expect it to work on CI (or colleagues' machines), too. Please make this deterministic. I do not really care which way - either fail all the time or make this work all the time. Even failing in some cases while working in others, when being consistent across environments, would be a better solution than this... :(
Comment From: jimrinhealthcare
We have what could be a similar issue that we only encountered when building a replacement Jenkins server.
When we build the application with our old Jenkins server (running on Amazon Linux), running the application (using java -jar
) succeeds, as expected.
When we build exactly the same code, with the new Jenkins server (running on Ubuntu Server), which uses the same JDK and Maven versions, running the application fails (on every OS we've tried) with the following error:
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
We've done a diff of the two JAR files, the only differences we found were timestamps in the MANIFEST files. MD5 hashes matched for all other class and JAR files in the archive.
Comment From: ipleten
@Autowire also has this problem. I wonder why it happens. We are running java in docker and the only difference is a host machine (java is the same, jar files defer only with timestamps). Is it related to machine kernel somehow? If I run the same docker on kernel 4.4 machine it works if it's on 4.14 I got cycle dependencies error. So what's a reason for that? Any thoughts?
P.S @Lazy annotation allows it to run but have some disadvantages.
Comment From: xtf2009
We have what could be a similar issue that we only encountered when building a replacement Jenkins server.
When we build the application with our old Jenkins server (running on Amazon Linux), running the application (using
java -jar
) succeeds, as expected.When we build exactly the same code, with the new Jenkins server (running on Ubuntu Server), which uses the same JDK and Maven versions, running the application fails (on every OS we've tried) with the following error:
```
APPLICATION FAILED TO START
Description: The dependencies of some of the beans in the application context form a cycle: ```
We've done a diff of the two JAR files, the only differences we found were timestamps in the MANIFEST files. MD5 hashes matched for all other class and JAR files in the archive.
Got same issue here,same code, jar packaged in one of our jenkins server throws :
The dependencies of some of the beans in the application context form a cycle
while jar package compiled by every other server and our PC works just fine.
Spring boot 2.5.2 + openjdk11(11+28) + maven3.6.3
All the jar files has exactly same md5 result excpet MANIFEST files.
Is anyone looking into this?This is so wired.
Comment From: liangjihua
I had the same problem, basically the same situation as described by others. This circular dependency problem occurs only for jar
built with docker by the CI server, no matter which machine the jar
is running on.
The MD5 of the files contained in the jar file is the same.
This may be a problem of order, I don't know if there is some kind of configuration or switch to track the creation of each bean in order to analyze the cause of this problem.
This problem is very specific, it is caused by compile time, not runtime.
Comment From: liangjihua
I used the InstantiationAwareBeanPostProcessor
interface to track the creation of each bean. Running on the same machine, a jar built by CI and a jar built on my own machine, the beans are initialized in a completely different order, even though their contents are the same. . .
Comment From: matiaspakua
Hello all, working on the same problem in a project with Spring, K8s on Azure platform, where we tried two alternatives:
1) first we tried putting @Lazy annotation on the beans where we think caused the problem (not the best option), and
2) second [THE SOLUTION], reading the comments where a few folks mention the diferences building on Ubuntu desktop and Ubuntu server, we decided to try our docker image based on maven 3, jdk8 but with "maven-alpine" instead of "maven-ubuntu". This was the solution for us. We hope this will be helpful.
Comment From: lchpersonal
I'm afraid that this is still a reality.
I had that problem and I was fighting with it for the past 3 days. In my case it was something more weird. I was developing and running from IntelliJ. Everything was fine there. When I deployed the software to another machine resembling the production environment, I got a circular dependency error. After lots of trial and error I realized what the difference was: intelliJ relies on the class files to run the application. We were making a jar. After I set IntelliJ to create a jar and run the jar on my machine I got the same error.
I was able to fix it with the workaround mentioned here. There is still the concern though why this thing happens. I enabled debugging for spring, and I saw that the
Eagerly caching bean 'XYZ' to allow for resolving potential circular references
messages were not appearing with the same order (comparing the classes vs jar execution). I also saw 45 less messages (compared to 144 that I was expecting to see). Again the only difference is the classes vs jar. The code is the same. This puzzles me as there shouldn't(?) be any differences between the 2 execution methods.So the questions are:
- Shouldn't the bean processing from Spring be deterministic? If not how can we make it?
- Could that be a timing issue? Should we expect differences across different hardware and OSes?
- Is there a difference between running spring applications from a jar versus from the class files? I searched but I couldn't find any difference.
I am at your disposal to provide any additional information as my team is very keen on having that resolved. The "random" manner of bean processing makes neither my teammates nor our managers confident. :(
I also encountered the same problem. In order to find the final cause, I traced the source code of springboot. I am glad that I finally found the root cause of the problem. The reason is that the order of instantiation of springboot beans is related to the order of the list of files returned from the jar package. The different platforms of the jar package lead to different order of the file list returned by jarFile.entries(). For specific logic, please see org.springframework.core.io.support.PathMatchingResourcePatternResolver#doFindPathMatchingJarResources (I am using springboot version 1.5.13). To solve this problem, it is necessary to do a natural sorting to solve the problem of inconsistent behavior of the same code in different environments.
in chinese: 我也遇到了同样的问题,为了找到最终的原因,我追踪了springboot的源码,很庆幸最终发现导致该问题的根本原因。原因在于,springboot bean的实例化顺序与从jar包返回的文件列表顺序有关。而打成jar包不同平台不一样导致了jarFile.entries()返回的文件列表顺序不同。具体逻辑请查看org.springframework.core.io.support.PathMatchingResourcePatternResolver#doFindPathMatchingJarResources (我使用的是springboot 1.5.13版本)。要想解决此问题,需要在做一次自然排序即可解决相同代码不同环境行为不一致的问题。
Comment From: liangjihua
I'm afraid that this is still a reality. I had that problem and I was fighting with it for the past 3 days. In my case it was something more weird. I was developing and running from IntelliJ. Everything was fine there. When I deployed the software to another machine resembling the production environment, I got a circular dependency error. After lots of trial and error I realized what the difference was: intelliJ relies on the class files to run the application. We were making a jar. After I set IntelliJ to create a jar and run the jar on my machine I got the same error. I was able to fix it with the workaround mentioned here. There is still the concern though why this thing happens. I enabled debugging for spring, and I saw that the messages were not appearing with the same order (comparing the classes vs jar execution). I also saw 45 less messages (compared to 144 that I was expecting to see). Again the only difference is the classes vs jar. The code is the same. This puzzles me as there shouldn't(?) be any differences between the 2 execution methods.
Eagerly caching bean 'XYZ' to allow for resolving potential circular references
So the questions are:
- Shouldn't the bean processing from Spring be deterministic? If not how can we make it?
- Could that be a timing issue? Should we expect differences across different hardware and OSes?
- Is there a difference between running spring applications from a jar versus from the class files? I searched but I couldn't find any difference.
I am at your disposal to provide any additional information as my team is very keen on having that resolved. The "random" manner of bean processing makes neither my teammates nor our managers confident. :(
I also encountered the same problem. In order to find the final cause, I traced the source code of springboot. I am glad that I finally found the root cause of the problem. The reason is that the order of instantiation of springboot beans is related to the order of the list of files returned from the jar package. The different platforms of the jar package lead to different order of the file list returned by jarFile.entries(). For specific logic, please see org.springframework.core.io.support.PathMatchingResourcePatternResolver#doFindPathMatchingJarResources (I am using springboot version 1.5.13). To solve this problem, it is necessary to do a natural sorting to solve the problem of inconsistent behavior of the same code in different environments.
in chinese: 我也遇到了同样的问题,为了找到最终的原因,我追踪了springboot的源码,很庆幸最终发现导致该问题的根本原因。原因在于,springboot bean的实例化顺序与从jar包返回的文件列表顺序有关。而打成jar包不同平台不一样导致了jarFile.entries()返回的文件列表顺序不同。具体逻辑请查看org.springframework.core.io.support.PathMatchingResourcePatternResolver#doFindPathMatchingJarResources (我使用的是springboot 1.5.13版本)。要想解决此问题,需要在做一次自然排序即可解决相同代码不同环境行为不一致的问题。
Great Job 👍
in chinese: 666
Comment From: darssy
@lchpersonal
The reason is that the order of instantiation of springboot beans is related to the order of the list of files returned from the jar package. The different platforms of the jar package lead to different order of the file list returned by jarFile.entries().
Great find. Although I'm not working on spring anymore, I think that the way to go (if anyone would be interested to fix this of course) would be first to process the source files and then try to create the object graph. That way @Lazy
will be used only when it's really needed. Otherwise a specific order of processing working for person A won't work for person B. My 2 cent's though.
Comment From: Dekari
Hello @liangjihua, all just wanted to clarify on the below "solution" noted above: "To solve this problem, it is necessary to do a natural sorting to solve the problem of inconsistent behavior of the same code in different environments."
Is there an example of how I can do this?
Also, last but not least, I would assume that eventually @Lazy is not at all an acceptable solution for this? or better say even with the use of @Lazy we may come across the same issue?
thanks in advance.
Comment From: alla-gofman
Hi, Have the same issue. Reproduced also as mentioned by @adamstyl in IntelliJ by running JAR Application. Works on Windows platform but does not on Linux and Docker.
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'XXX': Requested bean is currently in creation: Is there an unresolvable circular reference?
Comment From: murtazakhussain
I'm afraid that this is still a reality. I had that problem and I was fighting with it for the past 3 days. In my case it was something more weird. I was developing and running from IntelliJ. Everything was fine there. When I deployed the software to another machine resembling the production environment, I got a circular dependency error. After lots of trial and error I realized what the difference was: intelliJ relies on the class files to run the application. We were making a jar. After I set IntelliJ to create a jar and run the jar on my machine I got the same error. I was able to fix it with the workaround mentioned here. There is still the concern though why this thing happens. I enabled debugging for spring, and I saw that the messages were not appearing with the same order (comparing the classes vs jar execution). I also saw 45 less messages (compared to 144 that I was expecting to see). Again the only difference is the classes vs jar. The code is the same. This puzzles me as there shouldn't(?) be any differences between the 2 execution methods.
Eagerly caching bean 'XYZ' to allow for resolving potential circular references
So the questions are:
- Shouldn't the bean processing from Spring be deterministic? If not how can we make it?
- Could that be a timing issue? Should we expect differences across different hardware and OSes?
- Is there a difference between running spring applications from a jar versus from the class files? I searched but I couldn't find any difference.
I am at your disposal to provide any additional information as my team is very keen on having that resolved. The "random" manner of bean processing makes neither my teammates nor our managers confident. :(
I also encountered the same problem. In order to find the final cause, I traced the source code of springboot. I am glad that I finally found the root cause of the problem. The reason is that the order of instantiation of springboot beans is related to the order of the list of files returned from the jar package. The different platforms of the jar package lead to different order of the file list returned by jarFile.entries(). For specific logic, please see org.springframework.core.io.support.PathMatchingResourcePatternResolver#doFindPathMatchingJarResources (I am using springboot version 1.5.13). To solve this problem, it is necessary to do a natural sorting to solve the problem of inconsistent behavior of the same code in different environments. in chinese: 我也遇到了同样的问题,为了找到最终的原因,我追踪了springboot的源码,很庆幸最终发现导致该问题的根本原因。原因在于,springboot bean的实例化顺序与从jar包返回的文件列表顺序有关。而打成jar包不同平台不一样导致了jarFile.entries()返回的文件列表顺序不同。具体逻辑请查看org.springframework.core.io.support.PathMatchingResourcePatternResolver#doFindPathMatchingJarResources (我使用的是springboot 1.5.13版本)。要想解决此问题,需要在做一次自然排序即可解决相同代码不同环境行为不一致的问题。
Great Job 👍
in chinese: 666
Ohh my goodness, this is for real ?
well I was recently started facing this issue, everything works on my local but AWS it started giving this error.
After reading the above reply, I changed my filename to start something with "Z" so it goes in the end.
Comment From: snicoll
The randomness that affects you is a consequence of the context trying to do its best with what's being requested. If you use circular references, then you can be affected from what seems to be unrelated (such as adding a feature that creates a proxy that leads to the early cache to not get the aspect applied).
I understand that it can be problematic if you don't know about the cycle and you just realize at the wrong possible time because an environment change makes it fail. We've been improving bits and pieces in that area recently. Given how old this issue is, can someone please share a sample that exhibits the issue at hand (i.e. the difference of behavior for a change in base packages order). The original sample with a supported version fails consistently for me.
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.