This problem has been allowed to fester for a long time.
Serialisation creates all sorts of issues because it doesn't utilise
constructors or static factory methods.
I've had enough, I'm doing something about it.
As you may be aware, ObjectInputstream and ObjectOutputStream are extensible
and allow subclasses to substitute any object.
I'm considering creating an interface:
Interface DistributedObject {
SerialFactory substitute();
}
// Pseudo code; methods and constructors omitted.
public final class SerialFactory implements Externalizable {
private final Class clazz; // factory class or constructors class
private final String methodName; // constructor if null.
private final Class [] parameterTypes;
private final Object [] parameters;
}
It's straightforward to create object streams that substitute
DistributedObject's in the stream with SerialFactory and replace them using
reflection to call a constructor or static method during deserialisation.
This retains compatibility with existing Serialisation and Marshalling, it
preserves the object graph and allows distribution and construction of non
serializable final immutable objects. It doesn't suffer from readResolve's
circular reference issue either.
It allows object class evolution, migration of data, serial form is separate,
flexible and based on static method or constructor parameters, even a
completely different implementation can be used simply, by changing factory
method implementations (provided all references to an object being deserialised
refer to a compatible superclass or interface).
It prevents package classes from being published; eg a private class can
utilise a public class static factory method and extend a non serializable
class lacking a public no arg constructor (Serializable methods can't do that).
It also allows a transition period to migrate serializable objects to utilise
DistributedObject only, if necessary at some later point, removing lock in to
currently published serial form for much greater flexibility in future.
It would also allow heavyweight objects to be linked locally from persistant
storage or databases (which may be obtained via Services), only requiring
serialisation of a small amount of data to obtain a reference, allowing a
factory to perform the heavy lifting or construction required to obtain the
correct object to be linked into the object graph.
Yes, I'm aware that you can use reflection during deserialization to set final
fields to ensure immutability and invarients, unfortunately programmers seldom
use this trick, I want something simpler that gets rid of boilerplate code,
where most of the hard work is done for you, all the developer needs to do is
implement one method to construct a SerialFactory which utilises constructors
and factory methods
Sorry, I'm just getting fed up with legacy code making life hard.
Peter.