Spring Boot and Security upgrade to 2.7.0 throws org.springframework.security.core.context.SecurityContextImpl; local class incompatible:

Viewed 1192

When I upgrade my Spring Boot project from 2.6.7 to 2.7.0, I see below error. I presume the error occurred when incompatible Bean found with version 5.6.x. But when I checked Spring Security starter, I see it uses Spring Security 5.7

Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.InvalidClassException: org.springframework.security.core.context.SecurityContextImpl; local class incompatible: stream classdesc serialVersionUID = 560, local class serialVersionUID = 570

Full stack trace:

nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.InvalidClassException: org.springframework.security.core.context.SecurityContextImpl; local class incompatible: stream classdesc serialVersionUID = 560, local class serialVersionUID = 570
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47) ~[spring-core-5.3.20.jar:5.3.20]
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192) ~[spring-core-5.3.20.jar:5.3.20]
    at org.springframework.session.jdbc.JdbcIndexedSessionRepository.deserialize(JdbcIndexedSessionRepository.java:628) ~[spring-session-jdbc-2.7.0.jar:2.7.0]
    at org.springframework.session.jdbc.JdbcIndexedSessionRepository.access$1900(JdbcIndexedSessionRepository.java:133) ~[spring-session-jdbc-2.7.0.jar:2.7.0]
    at org.springframework.session.jdbc.JdbcIndexedSessionRepository$SessionResultSetExtractor.lambda$extractData$0(JdbcIndexedSessionRepository.java:898) ~[spring-session-jdbc-2.7.0.jar:2.7.0]
    at org.springframework.session.jdbc.JdbcIndexedSessionRepository$4.get(JdbcIndexedSessionRepository.java:650) ~[spring-session-jdbc-2.7.0.jar:2.7.0]
    at org.springframework.session.jdbc.JdbcIndexedSessionRepository$JdbcSession.getAttribute(JdbcIndexedSessionRepository.java:728) ~[spring-session-jdbc-2.7.0.jar:2.7.0]
    at org.springframework.session.PrincipalNameIndexResolver.resolveIndexValueFor(PrincipalNameIndexResolver.java:46) ~[spring-session-core-2.7.0.jar:2.7.0]
    at org.springframework.session.SingleIndexResolver.resolveIndexesFor(SingleIndexResolver.java:48) ~[spring-session-core-2.7.0.jar:2.7.0]
    at org.springframework.session.DelegatingIndexResolver.resolveIndexesFor(DelegatingIndexResolver.java:49) ~[spring-session-core-2.7.0.jar:2.7.0]
    at org.springframework.session.jdbc.JdbcIndexedSessionRepository$JdbcSession.lambda$save$11(JdbcIndexedSessionRepository.java:840) ~[spring-session-jdbc-2.7.0.jar:2.7.0]
    at org.springframework.transaction.support.TransactionOperations.lambda$executeWithoutResult$0(TransactionOperations.java:68) ~[spring-tx-5.3.20.jar:5.3.20]
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.20.jar:5.3.20]
    at org.springframework.transaction.support.TransactionOperations.executeWithoutResult(TransactionOperations.java:67) ~[spring-tx-5.3.20.jar:5.3.20]
    at org.springframework.session.jdbc.JdbcIndexedSessionRepository$JdbcSession.save(JdbcIndexedSessionRepository.java:837) ~[spring-session-jdbc-2.7.0.jar:2.7.0]
    at org.springframework.session.jdbc.JdbcIndexedSessionRepository$JdbcSession.access$200(JdbcIndexedSessionRepository.java:665) ~[spring-session-jdbc-2.7.0.jar:2.7.0]
    at org.springframework.session.jdbc.JdbcIndexedSessionRepository.save(JdbcIndexedSessionRepository.java:422) ~[spring-session-jdbc-2.7.0.jar:2.7.0]
    at org.springframework.session.jdbc.JdbcIndexedSessionRepository.save(JdbcIndexedSessionRepository.java:133) ~[spring-session-jdbc-2.7.0.jar:2.7.0]
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:226) ~[spring-session-core-2.7.0.jar:2.7.0]
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:193) ~[spring-session-core-2.7.0.jar:2.7.0]
    at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:145) ~[spring-session-core-2.7.0.jar:2.7.0]
    at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82) ~[spring-session-core-2.7.0.jar:2.7.0]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.20.jar:5.3.20]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:711) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:461) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:385) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:313) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:403) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:249) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:344) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:769) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.63.jar:9.0.63]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
1 Answers

Okay it turns out Spring Session created with version 2.6.x is not compatible with 2.7.0. In order to fix this, all existing user sessions should be invalidated and ask them login again. This can be done in 2 ways.

  1. Roll out Spring Boot 2.7.0 version change during off business hours when minimum number of users logged in.
  2. Or Put a specific down time and deploy the new version with Spring Boot 2.7.0

In any case let users know they need to login again

Related