Uploaded image for project: 'Infinispan'
  1. Infinispan
  2. ISPN-12739

Spring Session Repository should create a copy of the MapSession for each request

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • 12.1.0.CR1
    • 9.4.21.Final, 11.0.9.Final, 12.0.1.Final
    • Spring Integration
    • None
    • Hide

      The application could prevent the ConcurrentModificationException with a servlet filter that reads the session and synchronizes on it, before the servlet or other filters have a chance to modify session attributes.

      Show
      The application could prevent the ConcurrentModificationException with a servlet filter that reads the session and synchronizes on it, before the servlet or other filters have a chance to modify session attributes.
    • Undefined

      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.

            dberinde@redhat.com Dan Berindei (Inactive)
            dberinde@redhat.com Dan Berindei (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: