Consider the following code :
public class LIMSGrid extends ClientEventSource implements Focusable, FramingBlockWrapper {
//cell that is curently in edit mode
private CellCoord editingCell = null;
//framing block info
private FramingBlock framingBlock;
}
Now ClientEventSource extends a class that implements Serializable interface . The classes CellCoord and FramingBlock are POJOS with a bunch of getters and setters . FindBugs is complaining about the editingCell and framingBlock fields saying :
This Serializable class defines a non-primitive instance field which
is neither transient, Serializable, or java.lang.Object, and does not
appear to implement the Externalizable interface or the readObject()
and writeObject() methods. Objects of this class will not be
deserialized correctly if a non-Serializable object is stored in this
field.
Okay so everything is fine except how come it is saying that the instance fields are not "java.lang.Object" . This is totally misleading or I am missing some basics here ?
My guess (but it's only a guess) is that FindBugs doesn't trigger this warning if you reference java.lang.object instances, because it considers that in this case, your class is a generic container, which can hold any kind of object (like a Collection).
In that case, it's the responsibility of the user of the class to make sure that the object stored in the container is serializable if he wants the container to be serializable. (just like an ArrayList is serializable if and only if you store serializable objects inside the list).
You should make CellCoord and FramingBlock serializable to avoid that error. If you don't want to serialize them, you should set them as being transient.
The objects of the classes will not be deserialize correctly if there is any one of the object defined in the class extending the serializable will have non-primitive instance field which is neither transient, Serializable. because if any object of class want to save the its state , it won't be able to do so just because of one non-primitive instance field which is neither transient, Serializable.
Related
I am doing programming analysis for Java programs with soot. I customize a class which includes a field whose type is SootMethod. I want to save a large number of these objects and use them in another program. So, I find serialization meet my requirement. However, it triggers out the NotSerializableException because of the SootMethod.
What should I do if I want to save the objects with this SootMethod field? Why SootMethod is not serializable?
It's probably because SootMethod dose not implement java.io.Serializable so it is impossible to serialize instance of this Class , so if you want to serialize the object that contains a SootMethod type field you have 2 ways :
Make this field transient ! so it is possible to serialize the object , but when you deserialize the object this filed will be null.
Make SootMethod Class serializable by implement java.io.Serializable for this Class.
Generally a Class could be serializale if implements java.io.Serializable interface and all fields implements this interface too and if a field not implements it so this filed must be transient.
I am getting below Critical Sonar violation and don't know how to solve. Please help.
Fields in a "Serializable" class should either be transient or serializable (squid:S1948)
Fields in a Serializable class must themselves be either Serializable or transient even if the class is never explicitly serialized or deserialized. That's because under load, most J2EE application frameworks flush objects to disk, and an allegedly Serializable object with non-transient, non-serializable data members could cause program crashes, and open the door to attackers.
This rule raises an issue on non-Serializable fields, and on collection fields when they are not private (because they could be assigned non-Serializable values externally), and when they are assigned non-Serializable types within the class.
Rule saying that all object must be serialize or transit ,we don’t want to make it transit since we are saving it to activity , this member is type of “Object” class and we cannot make him serialize.
Example Class:
public class CharacteristicData implements ICharacteristicData, Serializable {
Object val;
String code;
Class<?> type; // Qualified class name
boolean isMandatory;
.........................
This class represents attributes. We can tell only in runtime its type(String , Date, Number etc... )
This may be obvious, but I'm not quite getting my head around Serialization:
I have a single object which holds the state of my application. This object references multiple other objects.
eg
ApplicationState implements Serializable
private ArrayList<SomeApplicationObjects>
private AnApplicationObject
private AnotherObject
All of these objects (someApplicationObjects, anApplicationObject, anotherObject) need to be serializable, as far as I understand.
But do objects THEY reference also need to be serializable? eg does SubObject here need to be serializable too? Does this essentially mean that every sub-object needs to be Serializable, recursively, from the ApplicationState down?
AnotherObject implements Serializable
private SubObject
Does this essentially mean that every sub-object needs to be Serializable, recursively
Assuming sub-object is the object you are using inside the class. Yes, the Objects used inside your Searializable type also be serializable.
Where as
All subtypes of a serializable class are themselves serializable
Yes, as reported in the javadoc of the interface serializable:
Serializability of a class is enabled by the class implementing the java.io.Serializable interface. Classes that do not implement this interface will not have any of their state serialized or deserialized. All subtypes of a serializable class are themselves serializable.
So if A has to be a serializable, subtypes of A (eg. B and C) have to be serializable too. So B and C should have also subtypes that are serializable, and so on..
As mention in java doc for serialization;
To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.
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.
It is mandatory that all sub-object need to be serializable.
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
If the Serializable interface is just a Marker-Interface that is used for passing some-sort of meta-data about classes in java - I'm a bit confused:
After reading the process of java's serialization algorithm (metadata bottom-to-top, then actual instance data top-to-bottom), I can't really understand what data cannot be processed through that algorithm.
In short and formal:
What data may cause the NotSerializableException?
How should I know that I am not supposed to add the implements Serializable clause for my class?
First of all, if you don't plan to ever serialize an instance of your class, there is no need to even think about serializing it. Only implement what you need, and don't try to make your class serializable just for the sake of it.
If your object has a reference (transitive or direct) to any non-serializable object, and this reference is not marked with the transient keyword, then your object won't be serializable.
Generally, it makes no sense to serialize objects that can't be reused when deserialized later or somewhere else. This could be because the state of the object is only meaningful here and now (if it has a reference to a running thread, for example), or because it uses some resource like a socket, a database connection, or something like that. A whole lot of objects don't represent data, and shouldn't be serializable.
When you are talking about NotSerializableException it is throw when you want to serialize an object, which has not been marked as Serializable - that's all, although when you extend non serializable class, and add Serializable interface it is perfectly fine.
There is no data that can't be serialized.
Anything your Serializable class has in it that is not Serializable will throw this exception. You can avoid it by using the transient keyword.
Common examples of things you can't serialize include Swing components and Threads. If you think about it it makes sense because you could never deserialize them and have it make sense.
All the primitive data types and the classes extend either Serializable directly,
class MyClass extends Serializable{
}
or indirectly,
class MyClass extends SomeClass{
}
SomeClass implements Serializable.
can be serialized. All the fields in a serializable class gets serialized except the fields which are marked transient. If a serializable class contains a field which is not serializable(not primitive and do not extend from serializable interface) then NotSerializableException will be thrown.
Answer to the second question : As #JB Nizet said. If you are going to write the instance of a class to some stream then and then only mark it as Serializable, otherwise never mark a class Serializable.
You need to handle the serialization of your own Objects.
Java will handle the primitive data types for you.
More info: http://www.tutorialspoint.com/java/java_serialization.htm
After reading the process of java's serialization algorithm (metadata bottom-to- top, then actual instance data top-to-bottom), I can't really understand what data cannot be processed through that algorithm.
The answer to this is certain system-level classes such as Thread, OutputStream and its subclasses which are not serializable. Explained very well on the oracle documents: http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html
Below is the abstract:
On the other hand, certain system-level classes such as Thread, OutputStream and its subclasses, and Socket are not serializable. Indeed, it would not make any sense if they were. For example, thread running in my JVM would be using my system's memory. Persisting it and trying to run it in your JVM would make no sense at all.
NotSerialisable exception is thrown when something in your serializable marked as serializable. One such case can be:
class Super{}
class Sub implements Serializable
{
Super super;
Here super is not mentioned as serializable so will throw NotSerializableException.
More practically, no object can be serialized (via Java's built-in
mechanism) unless its class implements the Serializable interface.
Being an instance of such a class is not a sufficient condition,
however: for an object to be successfully serialized, it must also be
true that all non-transient references it holds must be null or refer to
serializable objects. (Do note that that is a recursive condition.)
Primitive values, nulls, and transient variables aren't a problem.
Static variables do not belong to individual objects, so they don't
present a problem either.
Some common classes are reliably serialization-safe. Strings are
probably most notable here, but all the wrapper classes for primitive
types are also safe. Arrays of primitives are reliably serializable.
Arrays of reference types can be serialized if all their elements can be
serialized.
What data may cause the NotSerializableException?
In Java, we serialize object (the instance of a Java class which has already implemented the Serializable interface). So it's very clear that if a class has not implemented the Serializable interface, it cannot be serialized (then in that case NotSerializableException will be thrown).
The Serializable interface is merely a marker-interface, in a way we can say that it is just a stamp on a class and that just says to JVM that the class can be Serialized.
How should I know that I am not supposed to add the implements
Serializable clause for my class?
It all depends on your need.
If you want to store the Object in a database, you can
serialize it to a sequence of byte and can store it in the
database as persistent data.
You can serialize your Object to be used by other JVM working
on different machine.