Closed
Description
Piotr Findeisen opened SPR-11022 and commented
The -AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement
and- AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement
have double-check pattern and this results in a serious race condition resulting in @Autowired
-field-/methods not being autowired.
Explanation
In both -AutowiredFieldElement
,- AutowiredMethodElement
the volatile boolean cached
guards volatile Object[] cachedMethodArguments
but when the cachedMethodArguments
is populated the order is as follows:
- synchronize on this
- set
cachedMethodArguments
to new array (all fields null)- this gets flushed immediatelly, the
cachedMethodArguments
is volatile
- this gets flushed immediatelly, the
- populate
cachedMethodArguments
- this is not flushed, as array elements are not volatile
- set
cached = true
- this gets flushed immediatelly, the
cached
is volatile - and bang! now if some other thread enters the method, it will find
cached=true
,cachedMethodArguments
not null, but its contents may be pretty anything
- this gets flushed immediatelly, the
- leave synchronization block
solution
- set
cachedMethodArguments
only after this array is fully created and populated - or do not use double check pattern
Affects: 3.1.2
Referenced from: commits spring-attic/spring-framework-issues@57002b6, spring-attic/spring-framework-issues@da21a32, spring-attic/spring-framework-issues@a6f2f61