Serialization of an object from external API - java

I'm getting the java.io.NotSerializableException.
How can I serialize an object that does not implement java.io.Serializable?
I would like to serialize it in a stream.
I want to serialize an object from an external API. I can't modify this API.
In the external API, this object does not implement java.io.Serializable
Sure there are private fields, but there are a lot of getter and setter methods.
There are public static fields, and there is not a no-arg constructor, really, there is no constructor.
I think it's difficult to serialize it, isn't it?
Any suggestion?

if you can override the external API can create your own class which is a child of the external class.
Your child class can implement Serializable interface and you can serialize your class.
For ex-
ur external class is
class ExternalAPIClass
{
..
..
}
Class MyClass extends ExternalAPIClass implements Serializable
{
....
...
...
}

From what I understand from your question, you can create new instances of that object, and set their fields through setters. Then I suggest you use the getters to extract all the fields of the object into a Map, and then serialize that map.
Later you deserialize the map, create a new instance of the object, and set all the fields back with the setters.
Of course this is assuming there isn't any read only field that is set at construction time, like an ID. Because in that case the ids would be different.

Related

Why to serialize model class

Many times I see a model class will implement Serializable, but is never serialized.
What is purpose here to implement Serializable?
If serialization is not used, what will I miss? Is there any effect in the way the code communicates?
public class Stock implements Serializable{
private int stockId;
private String stockCode;
private String stockName;
//Getter and setter
}
What is purpose here to implement Serializable?
Just a marker to indicate the possibility provided to clients of the class for serializing instances of them if they wish.
For example, if you instantiate Stock class and that you want to save Stock instances in a file, you can do it thanks to this marker. APIs (for example Jaxb or Java native serialization mechanism) rely generally on the implementation of this interface to serialize class.
If serialization is not used, what will I miss? Is there any effect in
the way the code communicates?
It's is not used, you have zero overhead or transformation in the communication of the instance since it is a marker interface. Only, when the serialization occurs, the communication of the instance changes.
Serializable is just a marker interface without overhead*.
If you want class A to implement serializable and class A contains field with type Stock, Stock should also implement serializable.
May be there will be no direct Stock class instance serializations. But it will be serialized via class A instance.
Also implementing is necessary if you want Stock instance to become an argument of
type foo(? extends Serializable param)

Will objects of a custom class, inside an array, keep their data after serialization?

I am building a small application for keeping statistical data of some sort. I have a general question, before I start coding hard in this matter.
Say we have an object X of its own class, representing a sports match. It has several fields, among which is another object Y - also it's own class. Y will represent stats for a given game. The structure should be something like:
class Match {
Date date;
String venue;
ArrayList<Game>[10] gameList;
...
}
class Game{
int result;
int blah blah;
...
}
If I go and create a couple of Match objects, stored in an array for example, i can serialize an object, that contains this array of Matches, but when i deserialize it back, will I be able to keep the data inside the Game objects for example? Do I need to make each class used Serializable?
The reason for my worries are those lines from the JAVA Api Documentation:
During deserialization, the fields of non-serializable classes will
be initialized using the public or protected no-arg constructor of the
class. A no-arg constructor must be accessible to the subclass that is
serializable. The fields of serializable subclasses will be restored
from the stream.
When traversing a graph, an object may be encountered that does not
support the Serializable interface. In this case the
NotSerializableException will be thrown and will identify the class of
the non-serializable object.
Yes, you need to make Match class serializable. Making a class serialize means that you need to make all instance variables of that class serializable too (notice the recursive definition). In your example, to make Match class serializable, you need to make Game class serializable.
i guess the term
non-serializable classes
means such class doesn't implements the serializable interface there's exist classes in java doesn't implement serializable interface and you can't serialize them for example java.awt.BasicStroke you can't serialize any instance of of this class directly

Change class structure at runtime or get it into a anonymous class

I have
class A
{
String a;
String b;
//..getters, setters
}
Now I have ArrayList<? extends Object> resultData holding objects of class A and some other classes.
Basically I need this list 'resultData' to generate a Json file in some other API.
Now my question is while adding the class A objects to the list & some condition(X) is true I need a modified class A object (or any other anonymous class object) like:
class A
{
String a;
//..getters, setters
}
that is one particular object of class A shouldn't have field String b (before criticising, I'm doing this because I need such modified object for my particular JSon format & I don't want to define a new class definition that is used only once)
my last option is to make anonymous class like this: (& then add it to my List)
Object ob = new Object{
String b;
//..getters, setters
}
Also pls. suggest any other method of creating anonymous class with required structure.
Java is not meant for changing classes or creating new classes at runtime.
It is possible with a lot of effort, like generating java bytecode on the fly using a bytecode library like BCEL(http://commons.apache.org/proper/commons-bcel/) or even generate .java files and run javac to generate bytecode.
You could simply use a hash map like Map<String,Object> that "simulates" an object that can receive arbitrary fields. If you really need totally configurable classes, I would go this way. Of course, you would not have nice getters and setters for each property.
But why would you need nice setters / a nice class anyway? As the structure of the class is determined at runtime, you can write no code that depends on this class, as you do not know how it will look like.
if i'm getting you correctly, you need to get rid off field for serialization, to json format,
if im right, then make your field transient
other solution is to make super class with field which you want to serialize,
and make A to extend it
but modifying class on fly, it is not right way to go

Java Serialization and JavaBeans

Quick question, when marking an object as serializable, does it need to be a JavaBean? I mean, can you serialize an object that's not a JavaBean? Does it have any risk? Is it a good practice to always make an object a JavaBean if you intend to serialize it?
You are looking at it the wrong way. A Java Bean is any class that is
1) implements Serializable
2) Has a no-arg constructor
3) Has private members and setters/getters
So your question
marking an object as serializable, does it need to be a JavaBean?
has it backwards. Any class can be Serializable, by implementing the interface. Not all serializable classes define a Java Bean.
I mean, can you serialize an object that's not a JavaBean?
Yes.
Is it a good practice to always make an object a JavaBean if you
intend to serialize it?
It is good practice to design your classes with data encapsulation in mind. This means limiting access to fields directly, and using setters and getters where appropriate.
Of course, having a public no-arg constructor is not always necessary from an API point of view.
You really only need to follow the Java bean standard if you are going to use a library that depends on your classes being Java Beans.
Serializable is a marker Interface. Each Object you mark with the serializable interface can be sent trouh the wire or can be safed in a file. For example if you mark the class Foo with the serializable interface, you are able to safe the object state in a file and restore it later:
public class Foo implements java.io.Serializable{
public String name;
}
public main(){
Foo foo = new Foo();
foo.name="test";
try
{
FileOutputStream fileOut = new FileOutputStream("foo.file");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(foo);
}
}
That means it doesnt need to be a JavaBean. It could be a plain old java object, like the Foo Object example.
If you want to serialize an object of class, then that class need to implement serializable interface irrespective of it's bean (or) class with simple properties.
To serialize an object means to convert its state to a byte stream so that the byte stream can be reverted back into a copy of the object. A Java object is serializable if its class or any of its superclasses implements either the java.io.Serializable interface or its subinterface, java.io.Externalizable. Deserialization is the process of converting the serialized form of an object back into a copy of the object
This tutorial may help you
You can serialize any object that implements the Serializable interface, whether it's a JavaBean or not.
That said, the decision to make an object Serializable shouldn't be made lightly, because it locks in certain implementation details of the class thus reducing future flexibility.
See here for information on implementing Serializable.

How to serialize a non-serializable in Java?

How can I serialize an object that does not implement Serializable? I cannot mark it Serializable because the class is from a 3rd party library.
You can't serialise a class that doesn't implement Serializable, but you can wrap it in a class that does. To do this, you should implement readObject and writeObject on your wrapper class so you can serialise its objects in a custom way.
First, make your non-serialisable field transient.
In writeObject, first call defaultWriteObject on the stream to store all the non-transient fields, then call other methods to serialise the individual properties of your non-serialisable object.
In readObject, first call defaultReadObject on the stream to read back all the non-transient fields, then call other methods (corresponding to the ones you added to writeObject) to deserialise your non-serialisable object.
I hope this makes sense. :-)
Wrap the non-serializable class in a class of your own that implements Serializable. In your class's writeObject method, do whatever's necessary to serialize sufficient information on the non-serializable object so that your class's readObject method can reconstruct it.
Alternatively, contact the developer of the non-serializable class and tell him to fix it. :-)
You can use Kryo. It works on non serialized classes but classes needs registered aforehand.
If your class already implements the Serializable interface (required for serializing), all you must do is to declare the field you don't want to serialize with transient:
public transient String description;
If the class is not final, you can make your own class that extends it and implements Serializable. There are lots of other ways to serialize besides Java's built-in mechanism though.

Categories