Details
-
Bug
-
Resolution: Done
-
Major
-
9.4.21.Final, 11.0.9.Final, 12.0.1.Final
-
None
Description
MapSession uses a HashMap internally, but it does not have any synchronization. This means it is not safe for multiple requests to access the same MapSession object at the same time.
In particular, when fetching a session from the repository, AbstractInfinispanSessionRepository.getSession() wants to update the TTL of the session, which requires updating the session in the cache. If another thread is modifying the session at the same time, the MapSession serialization fails with a ConcurrentModificationException.
04:46:25.758 ERROR o.i.r.r.RpcManagerImpl - ISPN000073: Unexpected error while replicating java.util.ConcurrentModificationException: null at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1493) at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1526) at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1524) at org.infinispan.commons.marshall.MarshallUtil.marshallMap(MarshallUtil.java:52) at org.infinispan.marshall.exts.MapExternalizer.writeObject(MapExternalizer.java:63) at org.infinispan.marshall.exts.MapExternalizer.writeObject(MapExternalizer.java:31) at org.infinispan.marshall.core.GlobalMarshaller.writeInternal(GlobalMarshaller.java:638) at org.infinispan.marshall.core.GlobalMarshaller.writeInternalClean(GlobalMarshaller.java:643) at org.infinispan.marshall.core.GlobalMarshaller.lambda$findWriter$0(GlobalMarshaller.java:369) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:137) at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920) at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58) at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:111) at org.infinispan.marshall.core.ExternalJBossMarshaller.objectToObjectStream(ExternalJBossMarshaller.java:36) at org.infinispan.marshall.core.GlobalMarshaller.writeRawUnknown(GlobalMarshaller.java:617) at org.infinispan.marshall.core.GlobalMarshaller.writeUnknown(GlobalMarshaller.java:612) at org.infinispan.marshall.core.GlobalMarshaller.writeNonNullableObject(GlobalMarshaller.java:412) at org.infinispan.marshall.core.GlobalMarshaller.writeNullableObject(GlobalMarshaller.java:355) at org.infinispan.marshall.core.BytesObjectOutput.writeObject(BytesObjectOutput.java:26) at org.infinispan.commands.triangle.SingleKeyBackupWriteCommand.writeTo(SingleKeyBackupWriteCommand.java:125) at org.infinispan.marshall.exts.ReplicableCommandExternalizer.writeCommandParameters(ReplicableCommandExternalizer.java:71) at org.infinispan.marshall.exts.CacheRpcCommandExternalizer.marshallParameters(CacheRpcCommandExternalizer.java:118) at org.infinispan.marshall.exts.CacheRpcCommandExternalizer.writeObject(CacheRpcCommandExternalizer.java:114) at org.infinispan.marshall.exts.CacheRpcCommandExternalizer.writeObject(CacheRpcCommandExternalizer.java:65) at org.infinispan.marshall.core.GlobalMarshaller.writeInternal(GlobalMarshaller.java:638) at org.infinispan.marshall.core.GlobalMarshaller.writeNonNullableObject(GlobalMarshaller.java:402) at org.infinispan.marshall.core.GlobalMarshaller.writeNullableObject(GlobalMarshaller.java:355) at org.infinispan.marshall.core.GlobalMarshaller.writeObjectOutput(GlobalMarshaller.java:183) at org.infinispan.marshall.core.GlobalMarshaller.writeObjectOutput(GlobalMarshaller.java:176) at org.infinispan.marshall.core.GlobalMarshaller.objectToBuffer(GlobalMarshaller.java:305) at org.infinispan.remoting.transport.jgroups.JGroupsTransport.marshallRequest(JGroupsTransport.java:1031) at org.infinispan.remoting.transport.jgroups.JGroupsTransport.sendCommand(JGroupsTransport.java:1217) at org.infinispan.remoting.transport.jgroups.JGroupsTransport.sendToMany(JGroupsTransport.java:276) at org.infinispan.remoting.rpc.RpcManagerImpl.sendToMany(RpcManagerImpl.java:390) at org.infinispan.interceptors.distribution.TriangleDistributionInterceptor.sendToBackups(TriangleDistributionInterceptor.java:490) at org.infinispan.interceptors.distribution.TriangleDistributionInterceptor.lambda$localPrimaryOwnerWrite$4(TriangleDistributionInterceptor.java:443) at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextThenApply(BaseAsyncInterceptor.java:82) at org.infinispan.interceptors.distribution.TriangleDistributionInterceptor.localPrimaryOwnerWrite(TriangleDistributionInterceptor.java:422) at org.infinispan.interceptors.distribution.TriangleDistributionInterceptor.handleSingleKeyWriteCommand(TriangleDistributionInterceptor.java:392) at org.infinispan.interceptors.distribution.TriangleDistributionInterceptor.visitPutKeyValueCommand(TriangleDistributionInterceptor.java:113) at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73) at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:55) at org.infinispan.interceptors.BaseAsyncInterceptor.lambda$new$0(BaseAsyncInterceptor.java:23) at org.infinispan.interceptors.InvocationSuccessFunction.apply(InvocationSuccessFunction.java:25) at org.infinispan.interceptors.impl.SimpleAsyncInvocationStage.addCallback(SimpleAsyncInvocationStage.java:70) at org.infinispan.interceptors.InvocationStage.thenApply(InvocationStage.java:45) at org.infinispan.interceptors.BaseAsyncInterceptor.asyncInvokeNext(BaseAsyncInterceptor.java:225) at org.infinispan.interceptors.impl.EntryWrappingInterceptor.setSkipRemoteGetsAndInvokeNextForDataCommand(EntryWrappingInterceptor.java:734) at org.infinispan.interceptors.impl.EntryWrappingInterceptor.visitPutKeyValueCommand(EntryWrappingInterceptor.java:337) at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73) at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndFinally(BaseAsyncInterceptor.java:151) at org.infinispan.interceptors.locking.AbstractLockingInterceptor.lambda$nonTxLockAndInvokeNext$1(AbstractLockingInterceptor.java:297) at org.infinispan.interceptors.SyncInvocationStage.addCallback(SyncInvocationStage.java:42) at org.infinispan.interceptors.InvocationStage.andHandle(InvocationStage.java:65) at org.infinispan.interceptors.locking.AbstractLockingInterceptor.nonTxLockAndInvokeNext(AbstractLockingInterceptor.java:292) at org.infinispan.interceptors.locking.AbstractLockingInterceptor.visitNonTxDataWriteCommand(AbstractLockingInterceptor.java:128) at org.infinispan.interceptors.locking.NonTransactionalLockingInterceptor.visitDataWriteCommand(NonTransactionalLockingInterceptor.java:40) at org.infinispan.interceptors.locking.AbstractLockingInterceptor.visitPutKeyValueCommand(AbstractLockingInterceptor.java:82) at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73) at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndHandle(BaseAsyncInterceptor.java:184) at org.infinispan.statetransfer.StateTransferInterceptor.handleNonTxWriteCommand(StateTransferInterceptor.java:309) at org.infinispan.statetransfer.StateTransferInterceptor.handleWriteCommand(StateTransferInterceptor.java:252) at org.infinispan.statetransfer.StateTransferInterceptor.visitPutKeyValueCommand(StateTransferInterceptor.java:96) at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73) at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndFinally(BaseAsyncInterceptor.java:151) at org.infinispan.interceptors.impl.CacheMgmtInterceptor.updateStoreStatistics(CacheMgmtInterceptor.java:220) at org.infinispan.interceptors.impl.CacheMgmtInterceptor.visitPutKeyValueCommand(CacheMgmtInterceptor.java:182) at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73) at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:55) at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54) at org.infinispan.interceptors.DDAsyncInterceptor.visitPutKeyValueCommand(DDAsyncInterceptor.java:60) at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73) at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndExceptionally(BaseAsyncInterceptor.java:124) at org.infinispan.interceptors.impl.InvocationContextInterceptor.visitCommand(InvocationContextInterceptor.java:90) at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:57) at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54) at org.infinispan.interceptors.DDAsyncInterceptor.visitPutKeyValueCommand(DDAsyncInterceptor.java:60) at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73) at org.infinispan.interceptors.DDAsyncInterceptor.visitCommand(DDAsyncInterceptor.java:50) at org.infinispan.interceptors.impl.AsyncInterceptorChainImpl.invoke(AsyncInterceptorChainImpl.java:248) at org.infinispan.cache.impl.CacheImpl.executeCommandAndCommitIfNeeded(CacheImpl.java:1915) at org.infinispan.cache.impl.CacheImpl.put(CacheImpl.java:1430) at org.infinispan.cache.impl.CacheImpl.put(CacheImpl.java:2040) at org.infinispan.cache.impl.CacheImpl.put(CacheImpl.java:1415) at org.infinispan.cache.impl.CacheImpl.put(CacheImpl.java:235) at org.infinispan.cache.impl.AbstractDelegatingCache.put(AbstractDelegatingCache.java:116) at org.infinispan.cache.impl.EncoderCache.put(EncoderCache.java:195) at org.infinispan.spring.common.provider.SpringCache.put(SpringCache.java:159) at org.infinispan.spring.common.session.AbstractInfinispanSessionRepository.updateTTL(AbstractInfinispanSessionRepository.java:112) at org.infinispan.spring.common.session.AbstractInfinispanSessionRepository.lambda$getSession$1(AbstractInfinispanSessionRepository.java:105) at java.base/java.util.Optional.map(Optional.java:265) at org.infinispan.spring.common.session.AbstractInfinispanSessionRepository.getSession(AbstractInfinispanSessionRepository.java:105) at org.infinispan.spring.common.session.AbstractInfinispanSessionRepository.findById(AbstractInfinispanSessionRepository.java:79) at org.infinispan.spring.common.session.AbstractInfinispanSessionRepository.findById(AbstractInfinispanSessionRepository.java:32) at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getRequestedSession(SessionRepositoryFilter.java:351) at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:289) at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:192) at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:244)
The serialization error then leads to ISPN-12435, because the AckCollector created by TriangleDistributionInterceptor is not released.