본문 바로가기

개발/Spring

SpringSession을 이용한 로그인시 InvalidClassException 발생

728x90
반응형

 

SpringSession을 이용하여 로그인시 InvalidClassException 발생

26-Apr-2022 12:42:52.370 SEVERE [http-nio-9090-exec-1] org.apache.catalina.core.ApplicationDispatcher.invoke Servlet.service() for servlet [dispatcherServlet] threw exception
java.io.InvalidClassException: kr.co.app.common.vo.VO; local class incompatible: stream classdesc serialVersionUID = 7243479878155449130, local class serialVersionUID = 1
        at java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689)
        at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2012)
        at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1862)
        at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2169)
        at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1679)
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:493)
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:451)
        at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer.java:72)
        ...생략...
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.base/java.lang.Thread.run(Thread.java:829)
2022-04-26 12:42:52.449 ERROR 14667 --- [nio-9090-exec-1] o.s.b.w.servlet.support.ErrorPageFilter  : Forwarding to error page from request [/] due to exception [Failed to convert from type [byte[]] to type [java.lang.Object] for value '{-84, -19, 0, 5, 115, 114, 0, 34, 107, 114, 46, 99, 111, 46, 107, 105, 112, 116, 0, 1, 48}'; 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: kr.co.app.common.vo.VO; local class incompatible: stream classdesc serialVersionUID = 7243479878155449130, local class serialVersionUID = 1]
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [byte[]] to type [java.lang.Object] for value '{-84, -19, 0, 5, 115, 114, 0, 34, 107, 114}'; 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: kr.co.app.common.vo.VO; local class incompatible: stream classdesc serialVersionUID = 7243479878155449130, local class serialVersionUID = 1
        at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
        at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
        at org.springframework.session.jdbc.JdbcOperationsSessionRepository.deserialize(JdbcOperationsSessionRepository.java:677) ~[spring-session-jdbc-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.session.jdbc.JdbcOperationsSessionRepository.access$1600(JdbcOperationsSessionRepository.java:135) ~[spring-session-jdbc-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.session.jdbc.JdbcOperationsSessionRepository$SessionResultSetExtractor.lambda$extractData$0(JdbcOperationsSessionRepository.java:908) ~[spring-session-jdbc-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.session.jdbc.JdbcOperationsSessionRepository$8.get(JdbcOperationsSessionRepository.java:699) ~[spring-session-jdbc-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.session.jdbc.JdbcOperationsSessionRepository$JdbcSession.getAttribute(JdbcOperationsSessionRepository.java:779) ~[spring-session-jdbc-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.session.web.http.HttpSessionAdapter.setAttribute(HttpSessionAdapter.java:140) ~[spring-session-core-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at kr.co.app.LoginInterceptor.preHandle(LoginInterceptor.java:316) ~[classes/:na]
        ...생략...
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: kr.co.app.common.vo.VO; local class incompatible: stream classdesc serialVersionUID = 7243479878155449130, local class serialVersionUID = 1
        at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:78) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
        at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:36) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
        at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:385) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
        at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
        ... 86 common frames omitted
Caused by: java.io.InvalidClassException: kr.co.app.common.vo.VO; local class incompatible: stream classdesc serialVersionUID = 7243479878155449130, local class serialVersionUID = 1
        at java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689) ~[na:na]
        at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2012) ~[na:na]
        at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1862) ~[na:na]
        at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2169) ~[na:na]
        at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1679) ~[na:na]
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:493) ~[na:na]
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:451) ~[na:na]
        at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer.java:72) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
        at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:73) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
        ... 89 common frames omitted

<발생원인>

SpringSession을 이용하여 Session을 저장하면 SPRING_SESSION_ATTRIBUTES 테이블의 ATTRIBUTE_BYTES 컬럼(DataType:mediumblob)에 세션객체가 ObjectStream을 이용하여 저장된다.

CREATE TABLE `SPRING_SESSION_ATTRIBUTES` (
  `SESSION_PRIMARY_ID` char(36) NOT NULL,
  `ATTRIBUTE_NAME` varchar(200) NOT NULL,
  `ATTRIBUTE_BYTES` mediumblob NOT NULL DEFAULT '',
  PRIMARY KEY (`SESSION_PRIMARY_ID`,`ATTRIBUTE_NAME`),
  CONSTRAINT `SPRING_SESSION_ATTRIBUTES_FK` FOREIGN KEY (`SESSION_PRIMARY_ID`) REFERENCES `SPRING_SESSION` (`PRIMARY_ID`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

VO -&nbsp;serialVersionUID

세션에 저장되는 VO의 serialVersionUID 값을 변경하여 발생한 문제로 serialVersionUID 값을 기준으로 Deserialize 할때 InvalidClassException 이 발생되는 것으로 파악

<해결방안>

1. 세션에 저장되는 VO의 serialVersionUID 값을 기존값으로 변경하거나

2. SPRING_SESSION_ATTRIBUTES 테이블의 데이터를 삭제(TRUNCATE 또는 DELETE)하면 된다. (이 방법은 세션정보가 삭제되어 재로그인 해야하는 상황이 발생할 수 있다.)

<환경정보>

  • JDK 11
  • SpringBoot 2.1.7
  • MariaDB 10.3.x

 

728x90
반응형