Java Industry News
Java Code Stack #7
Long-term Persistence
Java Code Stack #7
Long-term Persistence
Jan. 1, 2000 12:00 AM
In my previous code stacks, I have used ObjectOutputStream extensively for serializing the state of my objects. This is a method I'm comfortable with, and I presume most of us are. But beware! ObjectOutputStream is not the right way to create a persistent copy of an object. When you serialize an object using ObjectOutputStream, all non-static and non-transient members along with the Class definition are pumped out in a binary format. While you can re-create the objects from this binary format with most of the available JVMs, it might not be so, maybe after a decade, when Sun decides to rewrite the Java Class implementation. So how can you save the state of an object in a Java implementation-independent format? Use XMLEncoder.
1. import java.beans.*;
2. import java.util.*;
3. import java.io.*;
4.
5. public class enc{
6. public static void main
7. (String ar[]) throws Exception{
8.
9. Hashtable hash=new Hashtable(1,1);
10. hash.put("afj","Moron");
11.
12. FileOutputStream fos=
new FileOutputStream("afj.xml");
13. BufferedOutputStream bos=
new BufferedOutputStream(fos);
14.
15.
16. /** Write a String Object first
17. and then a Hashtable object
18. to an output stream **/
19. XMLEncoder xe=new XMLEncoder(bos);
20. xe.writeObject(new String("Emp. List"));
21. xe.writeObject(hash);
22. xe.close();
23.
24.
25. /** Recreating the objects from
26. the XML File **/
27. FileInputStream fis=
new FileInputStream("afj.xml");
28. BufferedInputStream bis=
new BufferedInputStream(fis);
29.
30. XMLDecoder xd=new XMLDecoder(bis);
31. System.out.println((String)xd.readObject());
32.
33. Hashtable rec=(Hashtable)xd.readObject();
34. System.out.println("afj: "+rec.get("afj"));
35.
36. xd.close();
37.
38. }
39.}
When you encode the object as a XML file, output will look something like:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.4.0_01" class="java.beans.XMLDecoder">
<string>Emp. List</string>
<object class="java.util.Hashtable">
<void method="put">
<string>afj</string>
<string>Moron</string>
</void>
</object>
</java>
The XML file created using this method is portable and can be used across different JVM vendors running different runtime versions. Sun claims that XMLEncoder uses a Redundancy Elimination Algorithm for enhanced structural compactness, which means default values of objects are not written to the stream. This is something that you should check out.
#6 |
Dayal commented on 17 Dec 2002
If I change a class after it has been serialized using ObjectOutputStream, there does not seem to be a way to read in the old class using ObjectInputStream. This seems like an easier way if not the only way. Thanks.
|
#5 |
Frank Jennings commented on 11 Dec 2002
Yes you can encode custom objects with reference to other objects. And this a JVM-implementation-independent method of saving the object state. Exactly!
|
#4 |
Max Hrabrov commented on 11 Dec 2002
Can this method be used to write complex object hierarchies? I.e. custom objects with references to other objects? Essentially, can this be viewed as a JVM-version-independent method of serialization? Or is it not that robust?
|
#3 |
Mark Jennison commented on 11 Dec 2002
Or just use Oracle TopLink!
|
#2 |
Frank Jennings commented on 10 Dec 2002
java.beans.XMLEncoder and
java.beans.XMLDecoder ---> from 1.4
|
#1 |
Brijesh commented on 10 Dec 2002
this code does'nt compile with jdk1.3
I think the XMLEncoder and Decoder are new in 1.4.
|