spring-projects / spring-security

Spring Security

Home Page:http://spring.io/projects/spring-security

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Stop increasing serialVersionUIDs with every minor version

christopher-thumberger-whizus opened this issue · comments

Expected Behavior

The serialVersionUID field in Serializable classes should only be increased after introducing breaking changes (eg. new fields/methods) in a class.

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/Serializable.html

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization

Current Behavior

Currently, every Serializable class's serialVersionUID field is changed with every minor version.

Context

The company I work for uses a cluster of servers as a gateway that check Authentication/Authorization, before forwarding requests to other web applications. The servers in this cluster have to share sessions with each other. When doing a rolling update, the new and old versions cannot communicate with each other if they have different versions of spring security. This results in two negative outcomes.

  1. Negative impact on uptime, as we have to shutdown the entire cluster once in a while to remove all stale caches (some cluster only use embedded infinispan/hazelcast)
  2. Negative impact on user experience, as every user has to sign themselves in again each time such an update happens.

Dupe of #3737, which may have been closed incorrectly.

You can work around it by implementing a custom ObjectInputStream:

@Override
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
    ObjectStreamClass descriptor = super.readClassDescriptor();
    if (descriptor.getName().startsWith("org.springframework.security.")) {
        // ignore the serialized version and use the current version instead
        return ObjectStreamClass.lookupAny(Class.forName(descriptor.getName()));
    } else {
       return descriptor;
    }
}