When to Override writeObject/readObject? - java

Seems like a pretty straight forward question but I can't find a direct answer on the google's.
I have a simple IPC channel between two processes over UDP. Each message is wrapped in a header class (e.g. data-driven).
Ex.
enum Type
{
HELLO,
BYE,
LISTEN,
}
class Message
{
Type type;
Object data;
}
The Message is what I am sending to the ObjectOutputStream writeObject. This works fine for messages without a data payload (e.g. HELLO and BYE). However the LISTEN message sets the data attribute to a custom class (with all POD types) and it never seems to reach the other process. When I readObject on the other side I get nothing.
So my question is do I need a implement writeObject and readObject inside my Message class and/or inside the data's class-type?
--- Update 1 ---
Yes both the the Message type and underlying data type have implements Serializable and all eclipse was generate a serialVersionUID for me. Is that sufficient? I'm still not seeing the data portion of the message.

Make sure that all object written to ObjectOutputStream are Serializable.
The Javadoc clearly states:
Only objects that support the java.io.Serializable interface can be
written to streams.
Make sure that class Message implements Serializable or Externalizable interface.
Based on your update, Object data is an Object and by default, Object isn't Serializable. You can declare it as Serializable data. As mentioned before, Only Serializable objects can be written to OutputStream.

Implementing writeObject and readObject is not a necessary condition for an object to be serializable - they are only meant to customize serialization, not enable it.

By just implementing the Serializable interface an object is ready for serialitzation. However you can override those methods to allow for custom serialitzation. For instance, you might want to Serialize a GregorianCalendar. GregorianCalendar has a huge ammount of data (time zones etc), and you know, for instance, you only use the day, month and hour. Then you can avoid saving everyhing else by making those methods write just that parts.

Related

What is use of making classes serializable?

I have noticed many of the library classes "ArrayList", "String" even the exceptions are having a serialVersionUID. Why they have made it like this. Whats the practical use of doing that.FYI I am familiar with the concept of Serialization. Please point out the practical purpose of it.
For your reference find the serialversionUid for ClassCastException
public class ClassCastException extends RuntimeException {
private static final long serialVersionUID = -9223365651070458532L;
Where these object's state going to persist? And where will these objects state going to be retrieved ?
I am currently working in a project where we are making REST controllers whose input and output parameters will be JSON.We are creating simple POJOs for i/p and o/p parameters.I have seen people making those POJOs serializable .Whats the point in doing that ?
But I havent seen **out.readObject** or out.writeobject which is used to write and read the state of object.Will the POJO's state persist just making it serializable? If yes where it will be stored?
If you want the full story, read the spec: Java Object Serialization Specification.
[...] many of the library classes "ArrayList", "String" even the exceptions are having a serialVersionUID. Why they have made it like this.
To support backwards compatibility when reading objects that were written in an older version of the class. See Stream Unique Identifiers.
Where these object's state going to persist?
Wherever you decide. See Writing to an Object Stream.
And where will these objects state going to be retrieved ?
Wherever you put it. See Reading from an Object Stream.
[...] input and output parameters will be JSON. [...] I have seen people making those POJOs serializable. Whats the point in doing that ?
None. JSON is not using Java serialization. Java serialization creates a binary stream. JSON creates text.
Will the POJO's state persist just making it serializable? If yes where it will be stored?
No, see above.

Serializable class

What is the point to a serializable class? To my understanding its so that you can send objects across a network and know that on both ends that the object will be verified that it is the correct object. For example, if I have a server with a serializable class and want to send data to an app via object output stream, I can use the serializable class with the same UID on both ends to verify that the object is legitimate and not hacked? Please correct me if I'm wrong but that's how I am understanding the documentation on the serializable interface
Security and Serialization both are different.
Java serialization is to convert the objects to bytes. Period.
The optional UID field is to assure the serialized and deserialized object (structure) versions match.
Serialization is useful to convert an object into a file and reload it back into an object later in future, and of course you can send that file (stream) over the network also.
You're correct, but you can think of it more broadly.
You can convert a serializable class to bytes
You can add an object of this type to a serializable collection and it will be properly serialized (e.g. you can make a list of them and serialize the list if the list is serializable)
By the way, the serialVersionUID is optional. It will generate one on its own, though it will be a bit more fragile - if you change, for example, a method signature, the jvm will translate this to an altered signature and believe that the class is now incompatible with previous serialized versions, even if you haven't changed data fields. If you create your own you're essentially overriding this mechanism.

Use of Serializable other than Writing& Reading object to/from File

In Which Cases it is a good coding practice to use implements serializable other than Writing & Reading object to/from file.In a project i went through code. A class using implements serializable even if in that class/project no any Writing/Reading objects to/from file?
If the object leaves the JVM it was created in, the class should implement Serializable.
Serialization is a method by which an object can be represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object.
After a serialized object has been written into a file, it can be read from the file and deserialized that is, the type information and bytes that represent the object and its data can be used to recreate the object in memory.
This is the main purpose of de-serialization. To get the object information, object type, variable type information from a written(loosely speaking) representation of an object. And hence serialization is required in the first place, to make this possible.
So, whenever, your object has a possibility of leaving the JVM, the program is being executed in, you should make the class, implement Serializable.
Reading/Writing objects into files (Memory), or passing an object over internet or any other type of connection. Whenever the object, leaves the JVM it was created in, it should implement Serializable, so that it can be serialized and deserialized for recognition once it enters back into another/same JVM.
Many good reads at :
1: Why Java needs Serializable interface?
2: What is the purpose of Serialization in Java?
Benefits of serialization:
To persist data for future use.
To send data to a remote computer using client/server Java technologies like RMI , socket programming etc.
To flatten an object into array of bytes in memory.
To send objects between the servers in a cluster.
To exchange data between applets and servlets.
To store user session in Web applications
To activate/passivate enterprise java beans.
You can refer to this article for more details.
If you ever expect your object to be used as data in a RMI setting, they should be serializable, as RMI either needs objects Serializable (if they are to be serialized and sent to the remote side) or to be a UnicastRemoteObject if you need a remote reference.
In earlier versions of java (before java 5) marker interfaces were good way to declare meta data but currently we having annotation which are more powerful to declare meta data for classes.
Annotation provides the very flexible and dynamic capability and we can provide the configuration for annotation meta deta that either we want to send that information in byte code or at run time.
Here If you are not willing to read & write object then there is one purpose left of serialization is, declare metadata for class and if you are goint to declare meta data for class then personally I suggest you don't use serialization just go for annotation.
Annotation is better choice than marker interface and JUnit is a perfect example of using Annotation e.g. #Test for specifying a Test Class. Same can also be achieved by using Test marker interface.
There is one more example which indicate that Annotations are better choice #ThreadSafe looks lot better than implementing ThraedSafe marker interface.
There are other cases in which you want to send an object by value instead of by reference:
Sending objects over the network.
Can't really send objects by reference here.
Multithreading, particularly in Android
Android uses Serializable/Parcelable to send information between Activities. It has something to do with memory mapping and multithreading. I don't really understand this though.
Along with Martin C's answer I want to add that - if you use Serializable then you can easily load your Object graph to memory. For example you have a Student class which have a Deportment. So if you serialize your Student then the Department also be saved. Moreover it also allow you -
1. to rename variables in a serialized class while maintaining backwards-compatibility.
2. to access data from deleted fields in a new version (in other words, change the internal representation of your data while maintaining backwards-compatibility).
Some frameworks/environments might depend upon data objects being serializable. For example in J2EE, the HttpSession attributes must be serializable in order to benefit from Session Persistence. Also RMI and other dark ages artifacts use serialization.
Therefore, though you might not immediately need your data objects to be serializable, it might make sense to declare Serializable just in case (It is almost free, unless you need to go through the pain of declaring readObject/writeObject methods)

need of Serializable interface in java? As there are no methods in the interface. and how does it maintain state of an object?

classes which implement serializable interface what exactly they implement as there are no methods in the interface.And how does it help in maintaining state of object across a network.
It is a marker interface. Additional discussion can be found here: What is the use of marker interfaces in Java?
In short, the interface is used via reflection-based code that inspects the type information at run time, and if if the object in question implements that interfacre then certain actions are taken (in the case of Serializable: object is saved/loaded to/from a stream).
serializable is a marker interface. serializable interface makes java recognize the implementing class object can be serialized(means write the byte information of object into files or any other channels). So, it means if you want to make a class object can be serialized you have to make that class flagged with serializable interface. Otherwise, throws IOException like it wont serialze the object.
Why this Exception would be thrown? because, developer should decide about serializing an object and deserializing the same later would have any use or not. When there is no use of serializing developer wont want his object to be serialized by him or any other developer using his class. Take for example, Socket class; It wont implement serializable interface because If you can serialize socket and close application and launches the application again and deserialize the same socket object. In the mean while connected server through socket is down. Is there any use of serializing the socket class object?
It doesn't maintain state itself. But it marks the class as requiring serialisation, and the runtime then knows to serialise that class, and its components (excluding fields marked as transient).
It's useful to explicitly mark classes as being serialisable and fields as transient (i.e. not to be serialised). Otherwise you could inadvertently serialise everything in your program for transmission over the network. That likely is not what you want. You wouldn't want to serialise entities like factories. Nor credentials like passwords. Not to mention the payload size :-)
No interface maintains state, of course. It's a marker interface, like Remotable.
From Wikipedia:
.... serialization is the process of converting a data structure or object
into a sequence of bits so that it can be stored in a file, a memory buffer,
or transmitted across a network connection link .....
You can do things with serialized objects that you cannot do with non serialized objects. Instead of using using a webservice to pass data from client to server, you can put all of the info into a serialized bean and avoid any xml parsing and binding.
You can take a serialized bean and write it out to a file, save it in a database as a blob.
The serialized interface provides the ability for you to implement a level of persistence and durability.

Why its required to mark a class as serializable?

If a similar question is already posted on stackoverflow, pls just post the link.
What is the need to implement Serializable interface (with no methods) for objects which are to be serialized ?
The Java API says -
- If its not implemented then it will throw java.io.NotSerializableException.
That's because of the following code in ObjectOutputStream.java
............................
writeObject0(Object obj, boolean unshared){
.............
} else if (cl.isArray()) {
writeArray(obj, desc, unshared);
} else if (obj instanceof Serializable) {
writeOrdinaryObject(obj, desc, unshared);
} else {
throw new NotSerializableException(cl.getName());
}
................
But my question is why its necessary to implement Serializable and thereby inform or tell Java/JVM that a class can be serialized. (Is it only to avoid the exception ?).
In this is the case, If we write a similar functionality which writes objects to streams without the check of whether the class in an instanceOf Serializable, Will the objects of a class not implemneting Serializable serialized ?
Any help is appreciated.
It's a good question. The Serializable is know as a marker interface, and can be viewed as a tag on a class to identify it as having capabilities or behaviours. e.g. you can use this to identify classes that you want to serialise that don't have serialVersionUid defined (and this may be an error).
Note that the commonly used serialisation library XStream (and others) don't require Serializable to be defined.
It is needed so that the JVM can know whether or not a class can be safely serialized. Some things (database connections for example) contain state or connections to external resources that cannot really be serialized.
Also, you'll want to make sure that you put a serialVersionUID member in every serializable class to ensure that serialized objects can be de-serialized after a code change or recompile:
// Set to some arbitrary number.
// Change if the definition/structure of the class changes.
private static final long serialVersionUID = 1;
The serialization allows you to save objects directly to binary files without having to parse them to text, write the string out and then create a new object, and parse the string inputs when reading back in. The primary purpose is to allow you to save objects with all their data to a binary file. I found it to be extremely useful when having to work with linked lists containing lots of objects of the same type and I needed to save them and open them.
The reason is that not all classes can be serialized. Examples:
I/O stuff: InputStream, HTTP connections, channels. They depend on objects created outside the scope of the Java VM and there is no simple way to restore them.
OS resources like windows, images, etc.

Categories