java.util.ConcurrentModificationException when serializing non thread-safe maps
- by [email protected]
We have got some questions related to exceptions thrown during a map serialization like the following one (in this example, for a LRUMap):
java.util.ConcurrentModificationExceptionat org.apache.commons.collections.SequencedHashMap$OrderedIterator.next(Unknown Source)at org.apache.commons.collections.LRUMap.writeExternal(Unknown Source)at java.io.ObjectOutputStream.writeExternalData(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java(Inlined CompiledCode))at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java(Inlined CompiledCode))at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java(Inlined CompiledCode))at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java(Compiled Code))at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java(Compiled Code))at com.tangosol.util.ExternalizableHelper.writeSerializable(ExternalizableHelper.java(InlinedCompiled Code))at com.tangosol.util.ExternalizableHelper.writeObjectInternal(ExternalizableHelper.java(Compiled Code))at com.tangosol.util.ExternalizableHelper.serializeInternal(ExternalizableHelper.java(Compiled Code))at com.tangosol.util.ExternalizableHelper.toBinary(ExternalizableHelper.java(InlinedCompiled Code))at com.tangosol.util.ExternalizableHelper.toBinary(ExternalizableHelper.java(InlinedCompiled Code))at com.tangosol.coherence.servlet.TraditionalHttpSessionModel$OptimizedHolder.serializeValue(TraditionalHttpSessionModel.java(Inlined Compiled Code))at com.tangosol.coherence.servlet.TraditionalHttpSessionModel$OptimizedHolder.getBinary(TraditionalHttpSessionModel.java(Compiled Code))
This is caused because LRUMap is not thread safe, so if another thread is modifying the content of that same map while serialization is in progress, then the ConcurrentModificationException will be thrown. Also, the map must be synchronized. Other structures like java.util.HashMap are not thread safe too.
To avoid this kind of problems, it is recommended to use a thread-safe and synchronized map such as java.util.Map, java.util.Hashtable or com.tangosol.util.SafeHashMap. You may also need to use the synchronizedMap(Map) method from Class java.util.Collections.