spring-projects / spring-projects/spring-security

FactorGrantedAuthority causes Spring Session Data Redis to throw SerializationException under Graalvm Native Image

Open
#18,739 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage type: bug
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Describe the bug
I created a project which uses Spring Security Authorization Server (through spring boot starter oauth2 authorization server 4.0.1), Spring Data MongoDB (through spring boot starter data mongo 4.0.1) and Spring Session Data Redis (through spring session data redis 4.0.1). This project works perfectly under jvm. However, when I start turning it into Graalvm native image, with FactorGrantedAuthority registered through RegisterReflectionForBinding annotation; the image fails with the following stacktrace in the docker container when I login with postman:

org.springframework.data.redis.serializer.SerializationException: Cannot serialize
	at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:97) ~[na:na]
	at org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:255) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:169) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at java.base@25.0.2/java.lang.reflect.Method.invoke(Method.java:565) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at org.springframework.data.redis.core.BoundOperationsProxyFactory$BoundOperationsMethodInterceptor.doInvoke(BoundOperationsProxyFactory.java:177) ~[na:na]
	at org.springframework.data.redis.core.BoundOperationsProxyFactory$BoundOperationsMethodInterceptor.invoke(BoundOperationsProxyFactory.java:148) ~[na:na]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[na:na]
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:69) ~[na:na]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[na:na]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:222) ~[na:na]
	at jdk.proxy4/jdk.proxy4.$Proxy/sec48ab07.putAll(Unknown Source) ~[na:na]
	at org.springframework.session.data.redis.RedisIndexedSessionRepository$RedisSession.saveDelta(RedisIndexedSessionRepository.java:903) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.data.redis.RedisIndexedSessionRepository$RedisSession.save(RedisIndexedSessionRepository.java:891) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.data.redis.RedisIndexedSessionRepository.save(RedisIndexedSessionRepository.java:491) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.data.redis.RedisIndexedSessionRepository.save(RedisIndexedSessionRepository.java:267) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:229) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:145) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107) ~[na:na]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:199) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107) ~[na:na]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165) ~[na:na]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:77) ~[na:na]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[org.example.mongodbtest.MongodbtestApplication:11.0.15]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113) ~[na:na]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83) ~[org.example.mongodbtest.MongodbtestApplication:11.0.15]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72) ~[na:na]
	at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:685) ~[na:na]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[na:na]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) ~[na:na]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[org.example.mongodbtest.MongodbtestApplication:11.0.15]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903) ~[na:na]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1778) ~[na:na]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[org.example.mongodbtest.MongodbtestApplication:11.0.15]
	at java.base@25.0.2/java.lang.Thread.runWith(Thread.java:1487) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.lang.VirtualThread.run(VirtualThread.java:456) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.lang.VirtualThread$VThreadContinuation$1.run(VirtualThread.java:248) ~[na:na]
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer
	at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:64) ~[na:na]
	at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:33) ~[na:na]
	at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:94) ~[na:na]
	... 37 common frames omitted
Caused by: com.oracle.svm.core.jdk.UnsupportedFeatureError: SerializationConstructorAccessor class not found for declaringClass: org.springframework.security.core.authority.FactorGrantedAuthority (targetConstructorClass: java.lang.Object). Usually adding org.springframework.security.core.authority.FactorGrantedAuthority to serialization-config.json fixes the problem.
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:126) ~[na:na]
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.serialize.SerializationSupport.getSerializationConstructorAccessor(SerializationSupport.java:286) ~[na:na]
	at java.base@25.0.2/jdk.internal.reflect.ReflectionFactory.generateConstructor(ReflectionFactory.java:2439) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/jdk.internal.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:297) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectStreamClass.getSerializableConstructor(ObjectStreamClass.java:1319) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:371) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectStreamClass$Caches$1.computeValue(ObjectStreamClass.java:93) ~[na:na]
	at java.base@25.0.2/java.io.ObjectStreamClass$Caches$1.computeValue(ObjectStreamClass.java:90) ~[na:na]
	at java.base@25.0.2/java.io.ClassCache$1.computeValue(ClassCache.java:78) ~[na:na]
	at java.base@25.0.2/java.io.ClassCache$1.computeValue(ClassCache.java:75) ~[na:na]
	at java.base@25.0.2/java.lang.ClassValue.get(JavaLangSubstitutions.java:542) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ClassCache.get(ClassCache.java:89) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:76) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1035) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:325) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.util.ArrayList.writeObject(ArrayList.java:949) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.lang.reflect.Method.invoke(Method.java:565) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:946) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1395) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1317) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1451) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1408) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1317) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1451) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1408) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1317) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1451) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1408) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1317) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:325) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:46) ~[na:na]
	at org.springframework.core.serializer.Serializer.serializeToByteArray(Serializer.java:56) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:60) ~[na:na]
	... 39 common frames omitted`

<img width="803" height="371" alt="Image" src="https://github.com/user-attachments/assets/a1bce8cb-5b8c-4df7-b53b-9fca6252777e" />

I also tried to use RegisterReflection annotation with MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, but it results in another exception in the container:

<img width="788" height="126" alt="Image" src="https://github.com/user-attachments/assets/36ac5062-0a7f-4834-8bc7-2a98640e2be3" />

`org.springframework.data.redis.serializer.SerializationException: Cannot deserialize
	at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:112) ~[na:na]
	at org.springframework.data.redis.core.AbstractOperations.deserializeHashValue(AbstractOperations.java:447) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.data.redis.core.AbstractOperations.deserializeHashMap(AbstractOperations.java:391) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.data.redis.core.DefaultHashOperations.entries(DefaultHashOperations.java:386) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at java.base@25.0.2/java.lang.reflect.Method.invoke(Method.java:565) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at org.springframework.data.redis.core.BoundOperationsProxyFactory$BoundOperationsMethodInterceptor.doInvoke(BoundOperationsProxyFactory.java:177) ~[na:na]
	at org.springframework.data.redis.core.BoundOperationsProxyFactory$BoundOperationsMethodInterceptor.invoke(BoundOperationsProxyFactory.java:148) ~[na:na]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[na:na]
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:69) ~[na:na]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[na:na]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:222) ~[na:na]
	at jdk.proxy4/jdk.proxy4.$Proxy/sec48ab07.entries(Unknown Source) ~[na:na]
	at org.springframework.session.data.redis.RedisIndexedSessionRepository.getSession(RedisIndexedSessionRepository.java:531) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.data.redis.RedisIndexedSessionRepository.findById(RedisIndexedSessionRepository.java:500) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.data.redis.RedisIndexedSessionRepository.findById(RedisIndexedSessionRepository.java:267) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getRequestedSession(SessionRepositoryFilter.java:352) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:286) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:193) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at jakarta.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:221) ~[org.example.mongodbtest.MongodbtestApplication:6.1]
	at jakarta.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:221) ~[org.example.mongodbtest.MongodbtestApplication:6.1]
	at org.springframework.security.web.authentication.WebAuthenticationDetails.extractSessionId(WebAuthenticationDetails.java:61) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.security.web.authentication.WebAuthenticationDetails.<init>(WebAuthenticationDetails.java:46) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.security.web.authentication.WebAuthenticationDetailsSource.buildDetails(WebAuthenticationDetailsSource.java:40) ~[na:na]
	at org.springframework.security.web.authentication.WebAuthenticationDetailsSource.buildDetails(WebAuthenticationDetailsSource.java:30) ~[na:na]
	at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.setDetails(UsernamePasswordAuthenticationFilter.java:128) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:86) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:249) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:239) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) ~[na:na]
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) ~[na:na]
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:96) ~[na:na]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) ~[na:na]
	at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[na:na]
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[na:na]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) ~[na:na]
	at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) ~[na:na]
	at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) ~[na:na]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) ~[na:na]
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) ~[na:na]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) ~[na:na]
	at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) ~[na:na]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) ~[na:na]
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:237) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:195) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
    at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) ~[na:na]
	at org.springframework.web.filter.ServletRequestPathFilter.doFilter(ServletRequestPathFilter.java:52) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) ~[na:na]
	at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) ~[na:na]
	at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebSecurityConfiguration.java:317) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) ~[na:na]
	at org.springframework.web.filter.ServletRequestPathFilter.doFilter(ServletRequestPathFilter.java:52) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) ~[na:na]
	at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) ~[na:na]
	at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebSecurityConfiguration.java:317) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:355) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:272) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107) ~[na:na]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107) ~[na:na]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107) ~[na:na]
	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:142) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82) ~[org.example.mongodbtest.MongodbtestApplication:4.0.1]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107) ~[na:na]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:199) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[org.example.mongodbtest.MongodbtestApplication:7.0.2]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:107) ~[na:na]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165) ~[na:na]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:77) ~[na:na]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[org.example.mongodbtest.MongodbtestApplication:11.0.15]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113) ~[na:na]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83) ~[org.example.mongodbtest.MongodbtestApplication:11.0.15]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72) ~[na:na]
	at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:685) ~[na:na]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[na:na]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) ~[na:na]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[org.example.mongodbtest.MongodbtestApplication:11.0.15]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903) ~[na:na]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1778) ~[na:na]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[org.example.mongodbtest.MongodbtestApplication:11.0.15]
	at java.base@25.0.2/java.lang.Thread.runWith(Thread.java:1487) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.lang.VirtualThread.run(VirtualThread.java:456) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.lang.VirtualThread$VThreadContinuation$1.run(VirtualThread.java:248) ~[na:na]
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?
	at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:81) ~[na:na]
	at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:38) ~[na:na]
	at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:110) ~[na:na]
	... 87 common frames omitted
Caused by: org.graalvm.nativeimage.MissingReflectionRegistrationError: Cannot reflectively read or write field 'private static final long org.springframework.security.core.authority.FactorGrantedAuthority.serialVersionUID'. To allow this operation, add the following to the 'reflection' section of 'reachability-metadata.json' and rebuild the native image:
  {
    "type": "org.springframework.security.core.authority.FactorGrantedAuthority",
    "fields": [
      {
        "name": "serialVersionUID"
      }
    ]
  }
The 'reachability-metadata.json' file should be located in 'META-INF/native-image/<group-id>/<artifact-id>/' of your project. For further help, see https://www.graalvm.org/latest/reference-manual/native-image/metadata/#reflection⁠
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.MissingReflectionRegistrationUtils.reportAccessedField(MissingReflectionRegistrationUtils.java:79) ~[na:na]
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.UnsafeFieldUtil.getFieldOffset(UnsafeFieldUtil.java:46) ~[na:na]
	at java.base@25.0.2/jdk.internal.misc.Unsafe.staticFieldOffset(Unsafe.java:49) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.fieldaccessor.UnsafeFieldAccessorImpl.<init>(UnsafeFieldAccessorImpl.java:56) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.fieldaccessor.UnsafeStaticFieldAccessorImpl.<init>(UnsafeStaticFieldAccessorImpl.java:42) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.fieldaccessor.UnsafeQualifiedStaticFieldAccessorImpl.<init>(UnsafeQualifiedStaticFieldAccessorImpl.java:39) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.fieldaccessor.UnsafeQualifiedStaticLongFieldAccessorImpl.<init>(UnsafeQualifiedStaticLongFieldAccessorImpl.java:33) ~[na:na]
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.fieldaccessor.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:78) ~[na:na]
	at java.base@25.0.2/jdk.internal.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:2434) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.lang.reflect.Field.acquireOverrideFieldAccessor(Field.java:1195) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.lang.reflect.Field.getOverrideFieldAccessor(Field.java:130) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.lang.reflect.Field.getLong(Field.java:664) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectStreamClass.getDeclaredSUID(ObjectStreamClass.java:1583) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:355) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectStreamClass$Caches$1.computeValue(ObjectStreamClass.java:93) ~[na:na]
	at java.base@25.0.2/java.io.ObjectStreamClass$Caches$1.computeValue(ObjectStreamClass.java:90) ~[na:na]
	at java.base@25.0.2/java.io.ClassCache$1.computeValue(ClassCache.java:78) ~[na:na]
	at java.base@25.0.2/java.io.ClassCache$1.computeValue(ClassCache.java:75) ~[na:na]
	at java.base@25.0.2/java.lang.ClassValue.get(JavaLangSubstitutions.java:542) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ClassCache.get(ClassCache.java:89) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:76) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:478) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1927) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1785) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2101) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1620) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readObject(ObjectInputStream.java:487) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readObject(ObjectInputStream.java:445) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.util.ArrayList.readObject(ArrayList.java:982) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.lang.reflect.Method.invoke(Method.java:565) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:976) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2302) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2133) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1620) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream$FieldValues.<init>(ObjectInputStream.java:2480) ~[na:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2327) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2133) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1620) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream$FieldValues.<init>(ObjectInputStream.java:2480) ~[na:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2327) ~[org.example.mongodbtest.MongodbtestApplication:na]
    at java.base@25.0.2/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2133) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1620) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream$FieldValues.<init>(ObjectInputStream.java:2480) ~[na:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2327) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2133) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1620) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readObject(ObjectInputStream.java:487) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at java.base@25.0.2/java.io.ObjectInputStream.readObject(ObjectInputStream.java:445) ~[org.example.mongodbtest.MongodbtestApplication:na]
	at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer.java:71) ~[na:na]
	at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:76) ~[na:na]
	... 89 common frames omitted

To Reproduce

  1. Setup a project with the said dependencies (may omit Spring Data MongoDB as this is just my effort trying to use MongoDB as the authentication database instead of in-memory or SQL DB)
  2. Add RegisterReflectionForBinding annotation to register FactorGrantedAuthority for serialization
Image
  1. Run maven spring boot build image no fork with native profile to build native docker image
  2. Docker run the image
  3. Populate the database (or use in-memory user details, registered client, roles, authorities, etc.)
  4. Call login endpoint with postman
    Expected behavior
    I should be able to login with authorization server and be redirected to login success handler's specified endpoint, with the following postman screen (captured under jvm)
Image

Sample
Will work on one asap

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with FactorGrantedAuthority and the reported GraalVM Native Image serialization failure, using the login-through-Postman path with Spring Session Data Redis as the reproduction entry point. Done means the native image can save the Redis-backed session without throwing the reported SerializationException.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, redis, spring
Domain
backend, databases, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.