Problems with Swing's new XMLOutputStream class

Find out what's wrong, from the perspective of object-oriented design, with the XMLOutputStream class that's part of the newest version of Swing

I'm on vacation this month, so there won't be a full-blown column. I do want to post an abbreviated column, however, to give you a heads-up about what I consider an important object-oriented design issue. I first became aware of this problem during a presentation made by Sun's Swing team at a Java user group (JUG) meeting in San Jose, CA, on July 14.

XML serialization

At the recent JUG meeting, Sun Swing team member Philip Milne discussed a new persistence mechanism that's going to be added to Swing for the specific purpose of supporting file-based storage of JavaBeans. The long and the short of it is that an XMLOutputStream class, which works much like the classic ObjectOutputStream class (which flushes a binary version of an object to an arbitrary OutputStream), will be introduced into Swing. Objects sent to an XMLOutputStream are written out in a human-readable, XML-based syntax. This mechanism only works with JavaBeans, though; unlike ObjectOutputStream, you can't use it to store generic objects.

Personally, I'm not much of a fan of XML. I really like the idea of representing arbitrary data using a well-defined ASCII syntax, but XML itself is not a particularly good syntax for this purpose. Why not? Well, for one thing, it's just not compact enough. I much prefer something TeX-like, as in {b boldface} -- which is not only compact, but also enforces nesting in an intuitive way -- to XML's (<b>boldface</b>). Moreover, the whole notion of a DTD, a significant part of XML, is obscenely complicated for what it does. (For an introduction to XML, see Mark Johnson's JavaWorld article, "XML for the absolute beginner.") Why not just use a standard BNF grammar?

Regardless of my (or your) feelings about XML, one good thing about it is that it allows us to store the state of a JavaBean to a file in a well-defined, human-readable way. My problems with the new system have to do with the implementation presented by the Sun Swing team, not with the fact that it's using XML. Since the focus of the designers of this subsystem was on beans, the implementors correctly concluded that there was no point in storing the state of the entire object, since you can do this with standard serialization if you need to; rather, only the properties of the bean are stored to disk, and the list of property values is used to recreate the bean when it's reloaded. To reduce the size of the file, the persistence system creates a default instance of the bean (using the default constructor) and only stores those properties that do not have default values.

Unfortunately, the mechanism that's used to determine what properties need to be stored is at odds with both the JavaBeans specification and the principles of good object-oriented design. JavaBeans has always supported two ways of telling a BeanBox tool about properties. (A BeanBox is a drag-and-drop UI layout tool that's JavaBean-aware. The term was originally used to describe Sun's JavaBean Test container. See Mark Johnson's "The BeanBox: Sun's JavaBeans test container.") The simplest way to specify a JavaBean is to use getter and setter methods (more properly called accessors). Get/set functions are fundamentally incorrect in an object-oriented system, as I discussed last month. Exposing these compile-time properties to the runtime system by means of get/set methods is just unacceptable to a good object-oriented designer.

The designers of the JavaBeans spec were aware of this issue, so they provided another way to create a property sheet for the bean -- through a customizer class -- passed to the BeanBox via the BeanInfo object. If you implement the customizer as an inner class of the bean itself, then none of the compile-time properties need to be exposed, since the customizer can access them directly. From an object-oriented point of view, this is an ideal solution to the problem.

Unfortunately, the XMLOutputStream is oblivious to customizers. The class simply uses introspection to find get/set methods, and only stores those properties that have associated accessors. As a consequence, if you design your beans as a good object-oriented citizen should -- using customizers in full accordance with the JavaBeans specification -- you can't use the XML serialization system. When I brought up this issue at the JUG meeting, the only response I got was that my customizers would have to use accessors to initialize the bean, and this is an unacceptable solution as far as I'm concerned.

I believe the current limits on the XML serialization system are both unfortunate and completely unnecessary. I can think of lots of ways to solve the problem. The best solution is the introduction of a property keyword in the language, which would work like private but at the same time tag a field for a BeanBox. Alternatively, you could define a "magic field" (along the lines of serialVersionUID) that listed the fields you wanted to be stored, or even introduce a new naming convention (such as adding a _property suffix to a field name, as in background_color_property). As a last resort, it would be a simple matter to use BeanInfo's existing getPropertyDescriptors() method to get a list of properties. In theory, you could then provide private accessor methods that the XMLOutputStream (and BeanBox) could use to view or modify the properties. An even better approach would be to pass the customizer a Properties object that specified the desired values of those properties as established in the property-descriptor list. (The downside of this last suggestion is that you'd have to ship the BeanInfo object with the application.)

If you have any opinions on this issue, you can contact the Swing team at swing-feedback@java.sun.com.

Allen Holub has been working in the computer industry since 1979. He is widely published in magazines (Dr. Dobb's Journal, Programmers Journal, Byte, and MSJ, among others). He has seven books to his credit, and is currently working on an eighth that will present the complete sources for a Java compiler written in Java. After eight years as a C++ programmer, Allen abandoned that language for Java in early 1996. He now looks at C++ as a bad dream, the memory of which is mercifully fading. He's been teaching programming (first C, then C++ and MFC, now object-oriented design and Java) both on his own and for the University of California at Berkeley Extension since 1982. Allen offers both public classes and in-house training in Java and object-oriented design topics. He also does object-oriented design consulting and contract Java programming. Get information, and contact Allen, via his Web site: http://www.holub.com.

Learn more about this topic

Recommended
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more