Java Integration

JDOM is the most Java-centric of all the major APIs for processing XML. The JDOM developers have given a lot of thought to exactly how the JDOM classes fit into common Java systems such as the Java Collections API, Remote Method Invocation (RMI), and the I/O framework. Unlike DOM, the behavior of JDOM objects is very well defined with respect to Java operations such as cloning and serializing.

Serializing JDOM Objects

All the major JDOM classes such as Element, Document, Namespace implement the java.io.Serializable interface. This means JDOM objects can be passed between machines using remote method invocation (RMI) and stored in files using ObjectOutputStream and ObjectInputStream.

Of course just because something is possible doesn't mean it's a good idea. XML is itself a serialization format for JDOM objects, and it's a much more broadly supported one. What's not as broadly known is that pure textual XML is also generally much faster and smaller than Java's binary object serialization. There's very little reason to use serialized JDOM objects instead of passing genuine XML documents back and forth.

At the time of this writing, the long-term plan for JDOM serialization is still under discussion. While you can use object serialization to pass JDOM objects from one virtual machine to another, both of which have the same version of JDOM, using anything beyond that is up in the air. In particular, it is highly doubtful that an object you serialize today will be able to be deserialized tomorrow in a different version of JDOM. For long-term persistence, you should absolutely use XML documents instead of serialized objects.

Synchronizing JDOM Objects

For the most part, except for a few accidental exceptions, JDOM classes are not thread-safe. You cannot use a JDOM Document, Element, or other object safely in multiple threads simultaneously unless you synchronize it properly. If you build the object in one thread, and therefter only read from in different threads (in essence, if you treat the object as if it were immutable) then you may be OK. But if you plan to write to or modify the object, you're going to have to synchronize your objects.

Testing Equality

All the core JDOM classes (Element, Attribute, ProcessingInstruction, etc.) implement the equals() method. In all cases, the test is for object identity. In other words, element1.equals(element2) if and only if element1 == element2. That is, element1 is the same element as element2.

The reasoning is that order and position are significant in XML documents. Thus two nodes can’t be equal unless they are in fact the same node. For example, consider the two Price elements in this XML fragment:

  <Item>
    <Name>2002 Toyota Camry</Name>
    <Price>$10,000</Price>
  </Item>
  <Item>
     <Name>1976 AMC Gremlin</Name>
    <Price>$10,000</Price>
  </Item>

The two Price elements are character-for-character identical. However, one is a very good price and one is a very bad price because of what their positions in the document.

This behavior is enforced by implementing the equals() method with an == test and making the method final. A typical JDOM equals() method is defined thusly:

  public final boolean equals(Object o) {
    return (this == o);
  }

Hash codes

Because JDOM tests for equality based on object identity, the default hashCode() implementation inherited from java.lang.Object suffices. However, to prevent subclasses from violating this contract, the hashCode() method is implemented as a final method that calls super.hashCode(). That is, it looks like this:

 public final int hashCode() {
    return super.hashCode();
  }

Thus it cannot be overridden, and subclasses cannot change its behavior.

String representations

The JDOM toString() methods produce strings that look like these:

[Document:  No DOCTYPE declaration, Root is [Element: <html 
 [Namespace: http://www.w3.org/1999/xhtml]/>]]
[Element: <html [Namespace: http://www.w3.org/1999/xhtml]/>]
[Attribute: xml:lang="en"]
[Text:
]
[Attribute: type="text/css"]
[Attribute: rel="stylesheet"]
[Text: Latest Version: ]
[Element: <a [Namespace: http://www.w3.org/1999/xhtml]/>]
[Attribute: href="http://www.rddl.org/"]
[Text: June 16, 2002]

They are suitable for debugging, but not for display to an end user. In particular, they are not the serialized form of the XML node the object represents. To serialize a JDOM object onto a stream or into a String, use an XMLOutputter chained to a StringWriter. Do not use toString().

Cloning

All the core JDOM classes implement Cloneable. Except for Namespace objects (which are immutable), all clones are deep clones. For example, cloning an element makes a copy of the element's contents as well. The clone does not have a parent, and can be inserted into the same document or a different document.


Copyright 2001, 2002 Elliotte Rusty Haroldelharo@metalab.unc.eduLast Modified August 23, 2002
Up To Cafe con Leche