Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ensure consistency of enums in Java serialization?

When I serialize an object, I can use the serialVersionUID mechanism at the class level to ensure the compatibility of the two types.

However, what happens when I serialize fields of enum values? Is there a way to ensure that the enum type has not been manipulated between serialization and deserialization?

Suppose that I have an enum like OperationResult {SUCCESS, FAIL}, and a field called "result" in an object that is being serialized. How do I ensure, when the object is deserialized, that result is still correct even if someone maliciously reversed the two? (Suppose the enum is declared elsewhere as a static enum)

I am wondering out of curiosity - I use jar-level authentication to prevent manipulation.

like image 850
Uri Avatar asked Jun 16 '10 22:06

Uri


People also ask

Can we serialize enum in Java?

Because enums are automatically Serializable (see Javadoc API documentation for Enum), there is no need to explicitly add the "implements Serializable" clause following the enum declaration. Once this is removed, the import statement for the java. io.

Can we serialize enums?

To serialize an enum constant, ObjectOutputStream writes the value returned by the enum constant's name method. To deserialize an enum constant, ObjectInputStream reads the constant name from the stream; the deserialized constant is then obtained by calling the java.

Is serializable consider declaring a serialVersionUID?

However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during ...


2 Answers

From: http://www.theserverside.com/news/thread.tss?thread_id=50190#265205

The designers of enum feature decided there is no use case to create new enum objects at runtime. They took great care to not allow it.

Therefore, it looks like enum objects cannot be serialised and deserialised in their entirety. Also, from http://java.sun.com/javase/6/docs/platform/serialization/spec/serial-arch.html#6469:

Enum constants are serialized differently than ordinary serializable or externalizable objects. The serialized form of an enum constant consists solely of its name; field values of the constant are not present in the form. To serialize an enum constant, ObjectOutputStream writes the value returned by the enum constant's name method. To deserialize an enum constant, ObjectInputStream reads the constant name from the stream; the deserialized constant is then obtained by calling the java.lang.Enum.valueOf method, passing the constant's enum type along with the received constant name as arguments. Like other serializable or externalizable objects, enum constants can function as the targets of back references appearing subsequently in the serialization stream.

The process by which enum constants are serialized cannot be customized: any class-specific writeObject, readObject, readObjectNoData, writeReplace, and readResolve methods defined by enum types are ignored during serialization and deserialization. Similarly, any serialPersistentFields or serialVersionUID field declarations are also ignored--all enum types have a fixed serialVersionUID of 0L. Documenting serializable fields and data for enum types is unnecessary, since there is no variation in the type of data sent.

like image 92
Chris Dennett Avatar answered Oct 10 '22 20:10

Chris Dennett


Enums are read-replaced during deserialization. Quoting the serialization release notes for version 1.5:

The rules for serializing an enum instance differ from those for serializing an "ordinary" serializable object: the serialized form of an enum instance consists only of its enum constant name, along with information identifying its base enum type. Deserialization behavior differs as well--the class information is used to find the appropriate enum class, and the Enum.valueOf method is called with that class and the received constant name in order to obtain the enum constant to return.

like image 43
meriton Avatar answered Oct 10 '22 21:10

meriton