-
Notifications
You must be signed in to change notification settings - Fork 38.5k
markBeanAsCreated does not clear merged bean definition in a thread-safe fashion [SPR-14269] #18841
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
Comments
andyjojo commented the method markBeanAsCreated(String beanName) in AbstractBeanFactory is not thread safe. |
Juergen Hoeller commented Moving the |
andyjojo commented
|
andyjojo commented the error just occurs just because the too ofter clear the merged bean definition in multi threads for method protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, BeanDefinition containingBd) throws BeanDefinitionStoreException If thread A first clear merged bean then call getMergedBeanDefinition and create a new RootBeanDefinition, but thread B first clear the merged bean definition then call getMergedBeanDefinition and create another new RootBeanDefinition, there will be two different BeanDefinitions. |
Juergen Hoeller commented Since Have you tried to reproduce this against the latest |
andyjojo commented I have download latest code and running ./gradlew install then using 4.3.0.BUILD-SNAPSHOT, the issues can be reproduced. |
andyjojo commented if there are two different merged bean definitions for same beanName, the method InjectionMetadata.checkPropertySkipping(PropertyValues pvs) will not work correctly because same InjectionMetadata cached from CommonAnnotationBeanPostProcessor.findResourceMetadata for same beanName but different PropertyValues. |
Juergen Hoeller commented Good catch! Thanks for the insight, I'll have another pass today. |
Juergen Hoeller commented I've addressed this through synchronizing on The use of the |
andyjojo commented
|
Juergen Hoeller commented It'd be great if you could run your tests against the latest |
Juergen Hoeller commented Ouch, there might indeed be a remaining issue since the |
andyjojo commented not the issue of add method, the issue in your commit is same with no synchronized because the method getMergedLocalBeanDefinition(String beanName) are not synchronized in line 1176. |
Juergen Hoeller commented As far as I can see, with the
|
Juergen Hoeller commented BTW, I'm currently working on a whole range of 4.2.x backports, so this fix will appear in the upcoming |
andyjojo commented I do not mean getMergedLocalBeanDefinition need synchronized, I mean non-syncrhonzied getMergedLocalBeanDefinition case your commit not work. |
Juergen Hoeller commented That's true but it isn't meant to cover that case: The common lock is just intended to cover In any case, I can't reproduce the reported issue anymore with the |
Marcin Piela opened SPR-14269 and commented
When creating a context and then calling
getBean
on it from multiple threads we sometimes get aBeanInitializationException
fromRequiredAnnotationBeanPostProcessor.postProcessPropertyValues
.Attached is a simple maven project to reproduce. In a loop it:
The number of threads and max number of loop iterations can be passed as the first and second argument to the Main class.
Usage:
mvn clean package && java -jar target/spring-bug-1.0-SNAPSHOT-jar-with-dependencies.jar
We never get any errors when the getBean method is called from a single thread, so:
java -jar target/spring-bug-1.0-SNAPSHOT-jar-with-dependencies.jar 1
always works.
We don't get any errors for spring version 4.1.9, but as long as we switch to 4.2.0 or later the errors start occuring.
Example exception:
Affects: 4.2.6
Attachments:
Issue Links:
Referenced from: commits 9064d38, 71463fb, 933bbf2, 6efa058
Backported to: 4.2.7
The text was updated successfully, but these errors were encountered: