spring-projects / spring-statemachine

Spring Statemachine is a framework for application developers to use state machine concepts with Spring.
1.54k stars 607 forks source link

Issue with Serialization When Using stateMachineRedisPersistence.persist Method #1155

Open DoNotBugPlz opened 5 months ago

DoNotBugPlz commented 5 months ago

Springboot:3.2.2 JDK: 17 stateMachine: 4.0 stateMachine-redis: 4.0

When I call the stateMachineRedisPersistence.persist method, I encounter an error. The complete error message is: register this class use: kryo.register(org.springframework.statemachine.support.DefaultStateMachineContext.class); java.lang.IllegalArgumentException: Class is not registered: org.springframework.statemachine.support.DefaultStateMachineContext Note: To register this class use: kryo.register(org.springframework.statemachine.support.DefaultStateMachineContext.class); at com.esotericsoftware.kryo.Kryo.getRegistration(Kryo.java:579) at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:627) at org.springframework.statemachine.data.redis.RedisStateMachineContextRepository.serialize(RedisStateMachineContextRepository.java:94) at org.springframework.statemachine.data.redis.RedisStateMachineContextRepository.save(RedisStateMachineContextRepository.java:73) at org.springframework.statemachine.persist.RepositoryStateMachinePersist.write(RepositoryStateMachinePersist.java:46) at org.springframework.statemachine.persist.RepositoryStateMachinePersist.write(RepositoryStateMachinePersist.java:31) at org.springframework.statemachine.persist.AbstractStateMachinePersister.persist(AbstractStateMachinePersister.java:63) at [my service layer classes] I have already configured the serialization method for redisTemplate in my config, intending to use Jackson for serializing my state machine, but it seems not to take effect. Digging into the source code, I found that the actual implementation used within RepositoryStateMachinePersist is RedisStateMachineContextRepository, which uses a different serialization method than what I configured.

What should I do next to resolve this error? How can I ensure my configuration for Jackson serialization is applied correctly?

lizqlife commented 1 month ago

I encountered the same problem, buddy, have you solved it?

DoNotBugPlz commented 1 month ago

I encountered the same problem, buddy, have you solved it?

I solved it, though it seems like a rather ugly solution to me. I injected a Kryo class into the Spring container. Here's roughly how it was done: in a class annotated with @Configuration, I used the @Bean annotation to inject: Kryo kryo = new Kryo(); kryo.setRegistrationRequired(false); kryo.register(DefaultStateMachineContext.class); return kryo; This worked, but I found that when storing in Redis, it was in binary. I didn't have a particularly good method for this. In a similar project where I was writing an order service, I switched to the cola-component-statemachine, which is a bit more lightweight. If your project isn't complete yet, you might want to try this component."

lizqlife commented 1 month ago

I encountered the same problem, buddy, have you solved it?

I solved it, though it seems like a rather ugly solution to me. I injected a Kryo class into the Spring container. Here's roughly how it was done: in a class annotated with @configuration, I used the @bean annotation to inject: Kryo kryo = new Kryo(); kryo.setRegistrationRequired(false); kryo.register(DefaultStateMachineContext.class); return kryo; This worked, but I found that when storing in Redis, it was in binary. I didn't have a particularly good method for this. In a similar project where I was writing an order service, I switched to the cola-component-statemachine, which is a bit more lightweight. If your project isn't complete yet, you might want to try this component."

Thank you bro, I will try the two solutions you provided, which is very helpful to me. Thanks again and best wishes.