Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Do it the "Nescafe' " way -- with freeze-dried JavaBeans

How to use object serialization for bean persistence

Up to this point in the JavaWorld column on JavaBeans, we've discussed beans from the vantage point of how they behave within a single running Java program. The JavaBeans we've discussed so far only survive as long as there's an active reference to them, and as long as the program in which they run is executing. It would, however, be very useful for a software component to be able to survive the death of the program in which it runs, to be "resurrected" and run again when that program is revitalized; or maybe we'd want the component to be able to move from machine to machine, gathering information, or performing remote services. In either case, persistence is the key.

When the last reference to a bean goes out of scope, or when the program exits, all of a bean's "state" (the values of the bean's fields) is lost forever, unless we've saved enough information about what was inside the bean to reconstruct it later. Software object persistence is nothing more than saving information about an object so that it can be recreated at a different time and/or place. Object serialization is a means of implementing persistence by converting the object's state into a stream of bytes that can later be used to reconstruct a virtually identical copy of the original object.

In this article, we're going to take a look at some of the benefits that a persistence mechanism provides to a software component framework. We'll discuss the goals of the JavaBeans persistence approach, and then go over some introductory code examples of persistent JavaBeans.

A matter of simple storage

Though object persistence may seem like a new idea to you, you're probably more familiar with it than you know. Every file on your hard drive or floppy disk can be thought of as a persistent software object of one sort or another. For example, let's say you use a text editor to create a text file. At one point in time, there was a data structure in memory on some computer that contained the characters of your document. When you gave the editor the Save As command, you were really telling the program to persist the contents of its memory to a disk file. (Thank goodness the people who design user interfaces know better than to present information to users this way -- teaching my mom to use a word processor is hard enough without having to deal with menu items like Persist Memory State!)

The next time you run the text editor and you Load a file, the program reads the information in the text file and creates a structure in memory that is identical, more or less, to what was in memory when the file was last saved. The phrase "more or less" is significant because, typically, not all of the information about a software object is saved. For example, in the text editor there may be Undo information hanging around that goes away when the editor dies. The next time you start the editor, the file contents are there, but the Undo information is off in the Big Bit Bucket in the sky.

How object persistence and serialization work

Software object persistence works in precisely the same way as our file-saving example above: A software object in an object-oriented system can be serialized, or converted into a stream of bytes, which can be used to resurrect the object at some other place and/or time. If you're the developer who wrote the text editor discussed above, you may well have organized your program so that a document is a single object, which might be a single "monolithic" object that does everything, or an aggregation of many smaller objects that perform specialized tasks. If you ask the Document object for its serialized state, it simply returns a (possibly very long) string, which you then squirrel away on disk. When the user asks that a file be opened, your program opens the file, reads the string, and hands it to the Document class (or some class that knows how to create Document objects), and, voilà ! The Document object is risen from the dead.

Now, when the program told the Document object to serialize, the Document might have returned a long ASCII string with embedded newlines, which, when sent directly to a printer, would be readable. (Printing could actually be considered "serializing to paper," but only a geek would say it that way.) The Document also might have returned a string of compressed, illegible gibberish that you'd never be able to figure out in a thousand years, but which the Document object "understands" and can use to reconstruct that instance of the Document. This is an important point: Objects that serialize themselves into strings also know how to read those strings to restore themselves to their original state. An object of a certain class wrote that string, and given the same string later, that class had better know how to reconstruct the instance. Otherwise, persistence simply doesn't work.

Precisely how an object is serialized is arbitrary, at least in the general case. (Specific component technology specifications spell out the format of a serialized object, and that is anything but arbitrary.) That's why any reasonable word processor gives you the choice of one of a dozen or more file formats. Every word processor serializes its document objects in a different way, but since they're all documents, and documents share general traits like characters, fonts, paragraphs, leading, and so on, it's possible for software objects (and, therefore, word processors) to read each others' formats and interoperate. Likewise, software objects can be written to read and write each others' serialization formats and "pretend" to be instances of one another. We'll discuss this more in the section below entitled "Interoperation: works and plays well with others."

Objects that have been "freeze-dried" into strings can then be transmitted, stored, and otherwise manipulated as strings. The ability to store objects as strings gives system designers a lot of flexibility. Imagine you're designing the graphical user interface for a database application, and you've created a hot-looking component that manipulates the contents of a particular table or query result. You could serialize that customized component and save it in the database itself, say in a table called EDITORS, along with the name of the table. You could then organize your database application's user interface around combining these editing components, each of which specializes in manipulating a particular set of data. In order to change, for example, the screens used to edit particular tables, you need only change the associated serialized editing component in the EDITORS table, and the end-user application would automatically use the new component for future access to that table. (This is just an example. Obviously, there's a lot to be said for organizing your database applications around workflow instead of around the underlying data model.)

1 | 2 | 3 | 4 | 5 | 6 |  Next >
Resources
  • The document that fully describes the goals and API for serialization in Java is the Java Object Serialization Specification. You can read it and other serialization-related documents at http://java.sun.com/products/jdk/1.1/docs/guide/serialization/index.html
  • To find out more on the Externalizable interface, which gives you complete control of your serializable output format, see the Java documentation at http://java.sun.com/products/jdk/1.1/docs/api/java.io.Externalizable.html
  • A more in-depth discussion of the serialization interfaces appears at http://www.redbooks.ibm.com/SG247006/serial.htm
  • A FAQ containing advanced information about serialization (and remote method invocation, or RMI) can be found at http://java.sun.com/products/jdk/rmi/faq.html
  • Download the source code for this article in ZIP or Unix tar format.
  • You can also download the jar file with the customized, serialized bean inside.