Skip to content

ConcurrentModificationException when executing AutowireCapableBeanFactory.createBean [SPR-13493] #18071

@spring-projects-issues

Description

@spring-projects-issues

Richard Costine opened SPR-13493 and commented

This error is now happening sporadically during our acceptance tests. It looks to be caused by an internal list of strings (in spring's DefaultListableBeanFactory) which is updated via another thread, while an Iterator (backed by that same list of strings) is cycling over it.
If something is added (or deleted) to (or from) a collection while the collection is being iterated over, a ConcurrentModificationException will occur inside the next().

We have recently upgraded from Spring 3.1 to 4.1.6. With both Spring releases, we are using Akka and running in an OSGI container. When actors are instantiated, a spring createBean is done. That is where this sporadic exception now occurs.

39:15 ERROR [ akka.actor.OneForOneStrategy] - exception during creation
akka.actor.ActorInitializationException: exception during creation
at akka.actor.ActorInitializationException$.apply(Actor.scala:166) ~[com.typesafe.akka.actor_2.3.11.jar:na]
at akka.actor.ActorCell.create(ActorCell.scala:596) ~[com.typesafe.akka.actor_2.3.11.jar:na]
at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:456) ~[com.typesafe.akka.actor_2.3.11.jar:na]
at akka.actor.ActorCell.systemInvoke(ActorCell.scala:478) ~[com.typesafe.akka.actor_2.3.11.jar:na]
at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:263) ~[com.typesafe.akka.actor_2.3.11.jar:na]
at akka.dispatch.Mailbox.run(Mailbox.scala:219) ~[com.typesafe.akka.actor_2.3.11.jar:na]
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397) [com.typesafe.akka.actor_2.3.11.jar:na]
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [org.scala-lang.scala-library_2.11.6.v20150224-172222-092690e7bf.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [org.scala-lang.scala-library_2.11.6.v20150224-172222-092690e7bf.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [org.scala-lang.scala-library_2.11.6.v20150224-172222-092690e7bf.jar:na]
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [org.scala-lang.scala-library_2.11.6.v20150224-172222-092690e7bf.jar:na]
+*Caused by: java.util.ConcurrentModificationException: null
at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:711) ~[na:1.8.0_31]
at java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:734) ~[na:1.8.0_31]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:471) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]*+
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:412) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors(BeanFactoryUtils.java:186) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1105) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1139) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1042) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:342) ~[org.apache.servicemix.bundles.spring-beans_4.1.6.RELEASE_1.jar:na]
at com.ccadllc.firebird.core.actors.SpringInjector.apply(Injector.scala:102) ~[com.ccadllc.firebird.core.actors_6.0.0.20150820212456.jar:na]
at com.ccadllc.firebird.core.actors.Injected$$anonfun$apply$2.apply(Injector.scala:45) ~[com.ccadllc.firebird.core.actors_6.0.0.20150820212456.jar:na]
at com.ccadllc.firebird.core.actors.Injected$$anonfun$apply$2.apply(Injector.scala:45) ~[com.ccadllc.firebird.core.actors_6.0.0.20150820212456.jar:na]
at akka.actor.TypedCreatorFunctionConsumer.produce(Props.scala:343) ~[com.typesafe.akka.actor_2.3.11.jar:na]
at akka.actor.Props.newActor(Props.scala:252) ~[com.typesafe.akka.actor_2.3.11.jar:na]
at akka.actor.ActorCell.newActor(ActorCell.scala:552) ~[com.typesafe.akka.actor_2.3.11.jar:na]
at akka.actor.ActorCell.create(ActorCell.scala:578) ~[com.typesafe.akka.actor_2.3.11.jar:na]
... 9 common frames omitted

There is a similar issue here:

#17286

The ConcurrentModificationException issue didn't occur with 3.1 because a copy of the underlying list was Iterated over, not the original list. It looks like this was changed for performance reasons, but now it is causing our application to fail sporadically. I looked at code for the 4.2.1 release and the lists are still not accessed in a threadsafe manner.

If there are no plans to fix this code to ensure that the lists are accessed in a synchronized fashion (using a CopyOnWriteArrayList, or by giving the option for the lists to be copied before attempting to Iterate over them, or perhaps synchronizing on the lists around the iteration) is there any way for us to tell the context to use our own custom bean factory that does this? We are willing to sacrifice some performance degradation, in order to allow the application to still function similar to the way it was working under the old 3.1 release.

Currently we are synchronizing around the createBean, and for some cases it seems to fix the problem. However, this is a very large application and we feel the best way to ensure that it is fixed everywhere is to ensure that the beanFactory itself can handle access by multiple threads.


Affects: 4.1.6

Issue Links:

Referenced from: commits 097bcfb

1 votes, 4 watchers

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions