I'm having a problem when serializing and deserializing my objects in my project. I'm writing the object to a name.dat file.
However whenever i make a change in the Name class i can nolonger deserialize it, since it's two different objects.
Is there any way around this?
Your best options are:
Don't change your classes :-)
Throw away any serialized objects each time you change your classes.
Don't use Java object serialization.
Given that 1) and 2) are probably out of the question, option 3) should be given serious consideration. There a variety of alternatives to Java serialization, depending on the nature of the data you are persisting. These include:
Using Java properties files
Storing the data in a classical database (using SQL and the JDBC API)
Using an object-relational database mapping such as Hibernate
Using XML or JSON and a "binding" technology so that you can serialize / deserialize POJOs.
Finally, it is possible to implement class versioning using Java object serialization. However, it is tricky. And if you are continually changing the classes, then it is not going to be pleasant. Start by reading Versioning of Serializable Objects.
Related
Sometimes, we need to create some thrift objects in unit tests. We can do it by manually create object using Java code, like:
MyObj myObj = new MyObj();
myObj.setName("???");
myObj.setAge(111);
But which is not convenient. I'm looking for a way to create objects with some readable text.
We can convert thrift objects to JSON with TSimpleJSONProtocol, and get very readable JSON string, like:
{ "name": "???", "age": 111 }
But the problem is TSimpleJSONProtocol is write only, thrift can't read it back to construct an instance of MyObj.
Although there is a TJSONProtocol which supports to serialize and deserialize, but the generated JSON is not readable, it uses a very simplified JSON format and most of the field names are missing. Not convenient to construct it in tests.
Is there any way to convert thrift objects to readable string and also can convert it back? If TSimpleJSONProtocol supports converting back, which is just what I'm looking for
The main goal of Thrift is to provide efficient serialization and RPC mechanisms. What you want is something that is - at least partially - contrary to that. Human-readable data structures and machine processing efficiency are to a good extent conflicting goals, and Thrift favors the latter over the former.
You already found out about the TSimpleJson and TJson protocols and about their pros and cons, so there is not much to add. The only thing that is left to say is this: the protocol/transport stack of Thrift is simple enough.
This simplicity makes it possible to add another protocol based on your specific needs without much or overly complicated work. One could probably even write an XML protocol (if anyone really wants such bloatware) in short time.
The only caveat, especially vis-à-vis your specific case, is the fact that Thrift needs the field ID to deserialize the data. So you either need to store them in the data, or you need some other mechanism which is able to retrieve that field ID based on the field and structure names.
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)
Note: Due to the lack of questions like this on SO, I've decided to put one up myself as a Q&A
Serializing objects (using an ObjectOutputStream and an ObjectInputStream) is a method for storing an instance of a Java Object as data that can be later deserialized for use. This can cause problems and frustration when the Class used to deserialize the data does not remain the same (source-code changes; program updates).
So how can an Object be serialized and deserialized with an updated / downgraded version of a Class?
Here are a few common ways of serializing an object that can be deserialized in a backwards-compatible way.
1. Store the data in the JSON format using import and export methods designed to save all fields needed to recreate the instance. This can be made backwards-compatible by including a version key that allows for an update algorithm to be called if the version is too low. A common library for this is the Google Gson library which can represent Java objects in JSON as well as normally editing a JSON file.
2. Use the built-in java Properties class in a way similar to the method described above. Properties objects can be later stored using a stream (store()) written as a regular Java Properties file, or saved in XML (storeToXML()).
3. Sometimes simple objects can be easily represented with key-value pairs in a place where storing them in a JSON, XML, or Properties file is either too complicated or not neccessary (overkill one could say). In this case, an effective way of serializing the object could be using the ObjectOutputStream class to serialize a HashMap object containing key-value pairs where the key could be a String and the value could be an Object (HashMap<String,Object>). This allows for all of the object's fields to be stored as well as including a version key while providing much versatility.
Note: Although serializing an object using the ObjectOutputStream for persistence storage is normally considered bad convention, it can be used either way as long as the class' source code remains the same.
Also Note about versioning: Changes to a class can be safely made without disrupting deserialization using an ObjectOutputStream as long as they are a compatible change. As mentioned in the Versioning of Serializable Objects chapter of the Object Serialization Specification:
A compatible change is a change that does not affect the contract
between the class and its callers.
I am writing the service to implement the audit in our application wherein users can view the status of a particular entity before and after any modification and should also be able to roll it back. We have decided to store the XML Serialized object in the databse in XML_TYPE column.
I am new to serialization, I don't know how to achieve the same, any changes needs to be done to the object to be serialized or do we need to have any mapping XML. Can someone please suggest some good libraries, I understand there are lot of those available in the market like JAXB, JIBX, JABX, XStream and etc. Which one would be good and how to use it.
Any help is highly appreciated.
Regards,
Ravi.
Of course, the best for entities is having POJO's (Plain Old Java Objects). No strange properties, references or methods. It simplifies serializing and keeps your model objects neutral from frameworks and strange layers like persistence, UI, remote-access and so on.
XStream: simplicity
I'd suggest using XStream library for serializing. It tries to be the simplest way to serialize and deserialize objects to XML.
You should think searialization this way:
indicate what class is the object
try to serialize each property
So, these are the two problems to resolve in serializing. XStream lets you create a serializer (XStream class), (OPTIONALLY) indicate what tag name use for each class and (OPTIONALLY) indicate the aliases for properties.
So if you have something like:
package pack;
Person
+ mom: Person
+ dad: Person
it will write with no configuration:
<pack.Person>
<mom>
<pack.Person>
...
</pack.Person>
</mom>
<dad>
<pack.Person>
...
</pack.Person>
</dad>
</pack.Person>
But if you tell it to map package.Person to it will use that tag. You can tell it to write property "mom" as "mother" and things like that.
XStream xs = new XStream();
xs.alias("person", Person.class);
xs.aliasAttribute(Person.class, "mom", "mother");
References
XStream also lets you indicate what kind of references you want:
no references: serialize an object
each time it founds it in the object
tree
absolute references: the second time
an object is found it saves a
reference using the absolute path of
the first instance
(/people/person[4]/teacher)
relative references: the same, but
using a relative reference from this
point (../../person[4]/teacher)
JAXB is the standard. In the simplest (and most common case) you just annotate your entities with JAXB annotations, and use a Marshaller to marshal the object to XML.
You can use either Sun's reference implementation, or Apache JaxMe.
XStream is a good alternative as far as I know, although I haven't used it.
JAXB works well until I need to do something like serialize beans for which I cannot modify the source. If the bean doesn't have a default constructor or if it refers to objects I want to mark transient then I'm stuck writing a separate bean which I can annotate and then manually copy the information over from the other bean.
For instance, I wanted to serialize exception objects, but found that the only way to do that was use a hack that required using com.sun.* classes.
So, what alternatives are there? What's the next most popular xml serializing api? It would be nice to be able to do things like:
Choose at serialization time whether to include certain fields in the result. (marking things transient when running the serializer).
Handle loops in the object graph by using references or something other than just dying.
Perhaps annotate an object so that in version 1 it serializes things in one way and in version 2 it serializes them in another. Then when serializing I just choose which version of the object ot serialize.
Have a way to generate XSDs from annotations on an object.
Basically I just want more flexibility than I currently have with JAXB.
Well the standard answer for wanting a uber configurable serialisation framework is xstream.
JAXB is a spec, so you can pick from different implementations. EclipseLink JAXB (MOXy) has extensions for what you are asking:
Externalized Metadata
Useful when dealing with classes for which you cannot annotate the source or to apply multiple mappings to an object model.
http://bdoughan.blogspot.com/2010/12/extending-jaxb-representing-annotations.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/EclipseLink-OXM.XML
XPath Based Mapping
For true meet-in-the-middle OXM mapping:
http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html
http://bdoughan.blogspot.com/2011/03/map-to-element-based-on-attribute-value.html
http://bdoughan.blogspot.com/2010/07/xpath-based-mapping.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted/MOXyExtensions
JPA Compatibility
Including support for bi-directional relationships.
http://bdoughan.blogspot.com/2010/07/jpa-entities-to-xml-bidirectional.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA
Also look at JIBX. It's a good xml<->object mapper. My experience is though that if your objects have a somewhat funky relationships it's often easier to create a wrapper object that hides that complexity and then map that object with JIBX.
XStream is a popular XML serialisation library that claims to be able to serialize just about anyting, regardless of constructors or other problems (even deserialize final fields). Give it a try.
Requires no modifications to objects. Serializes internal fields, including private and final. Supports non-public and inner classes. Classes are not required to have default constructor.