I have a method
@Cacheable(value = USER_IDENTITIES_PROTO_CACHE)
public UserIdentitiesResponseOuterClass.UserIdentitiesResponse findUserIdentitiesProto(UUID userId) {
where UserIdentitiesResponseOuterClass.UserIdentitiesResponse
is a class generated by protobuff.
When using JVM everything works well but in the native image I am getting the exception
"Failure putting into cache: user_identities_proto. Cannot serialize"
I have tried to add
hints.serialization()
.registerType(TypeReference.of(UserIdentitiesResponseOuterClass.class))
.registerType(UserIdentitiesResponseOuterClass.UserIdentity.class)
.registerType(UserIdentitiesResponseOuterClass.UserIdentitiesResponse.class);
but it did not help.
I am using Redis as a cache and using JdkSerializationRedisSerializer
to serialize.
Content of proto file below:
syntax = "proto3";
package identity;
message UserIdentity {
string provider = 1;
string sub = 2;
}
message UserIdentitiesResponse {
UserIdentity primary = 1;
repeated UserIdentity identities = 2;
}
if an application is run in JVM mode (not native) protobuff object is successfully serialized/deserialized. But in native image the mentioned problem happens.
I am assuming the solution would be to add the runtime hints.serialization(), but as I mentioned I did it and it did not help, so something is still missing, but it’s not clear what exactly
How to fix it?
2
Answers
"Failure putting into cache: user_identities_proto. Cannot serialize" indicates that GraalVM cannot serialize the
UserIdentitiesResponse
object when you’re trying to cache it using Redis.The
@Cacheable
annotation in Spring uses Java’s default serialization mechanism, but protobuf classes do not support Java serialization out of the box. They need to be serialized using protobuf’s own serialization mechanisms.JdkSerializationRedisSerializer
relies on Java’s built-in serialization, which is incompatible with protobuf objects.You should use a different Redis serializer compatible with protobuf. Spring Data Redis provides a few options, but you might need to implement your own or find a third-party library that supports protobuf.
Use this solution. Add RuntmeHints to your spring initialization class and add all the classes you will cache.