Sponsored Link •
Bill Venners: In your talk you said JDOM taught you that "Thread safety is not necessary." Why not?
Elliotte Rusty Harold: Thread safety may be necessary in some applications that use JDOM, but in those applications, the synchronization probably belongs in the broader application that's calling JDOM. Many applications are not multi-threaded. And even those that are multi-threaded do not necessarily share JDOM objects between multiple threads. There's no reason to put the overhead of designing for multi-threaded applications into JDOM itself. If you need to share JDOM documents between multiple threads, then you can synchronize it at a higher level.
Bill Venners: By that overhead do you mean the performance hit at runtime, or the extra work programmers have to do to make JDOM multithreaded?
Elliotte Rusty Harold: Mostly the extra work that programmers have to do. I don't worry that much about performance. That's there too, but I think designing truly thread-safe code is incredibly difficult. It really requires an expert, and I'm not an expert in designing thread-safe code.
Bill Venners: You also said that "Live lists are trouble." What are live lists, and why are they trouble?
Elliotte Rusty Harold: Live lists have troubled both DOM and JDOM.
They are probably a little more trouble in JDOM because the issues haven't
been thought out in as much depth as in DOM. Let's say you have an
Element object, a
Document element, and you ask for the
children of that element—all the children, not just one. You get back
a list, and you iterate through the list. In JDOM you get back a
java.util.List. In DOM you get back a
NodeList. In both cases, imagine you delete an element from
the list as you're iterating through the list. Or you add an element to the list,
even within a single thread, modifying the list as you go. In JDOM and DOM, that
changes the children of that element.
You have a real reference to the real children of the element—that's what a live list is. And if you've got a multithreaded application, if another thread changes the list, you see that reflected immediately too. Live lists are useful for some purposes, although not for the most common case of reading through the list and iterating all the children. It is useful perhaps when you're modifying the list. However, both JDOM and DOM have a huge amount of extra complexity internally to support the liveness of their lists. It makes the code much harder to fix. Both JDOM and some DOM implementations have had serious bugs related to liveness of lists, in cases where the liveness failed even though it wasn't supposed to. And it makes it hard to evolve the code.
Bill Venners: So is there another kind of list, a dead list perhaps?
Elliotte Rusty Harold: Yes. Instead of returning a reference to the actual children, the API can return a copy of the list. The changes made to that list are not reflected in the original document from which the list came.
XOM lists, interestingly, are neither live nor dead. They are in-between, what I refer to as comatose.
In XOM, a change to the list does not change the
document. However, a change to a member of the list does change that
member back in the document. For example, in the list, you remove an element.
It is not removed from the document.
However, if in the list you change the name of an element, call
element.setName(), the name of the element changes in the
document too. The list references to the actual elements in the document, but
the list itself is not the same list used in the document.
Bill Venners: You also said you learned from JDOM to "keep everything in the same package."
Elliotte Rusty Harold: In JDOM, we had some major troubles with
serialization and parsing, because the parsing went into the
org.jdom.input package, the serialization went into the
org.jdom.output package, and the core classes were just in
org.jdom. We really needed friend functions. The parser or
builder needed to do things that we could not expose in the core package
without exposing them to other non-parser related classes.
For example, we wanted the parser to be able to create an element without verifying it. Generally speaking, when you construct a JDOM element, the name and properties of the element are verified to make sure the element is well-formed. JDOM wants to make sure that client programmers can't bypass those checks. However, if the parser is building the document, the parser has already made those checks. So in that case, it is perfectly reasonable to bypass those checks. Because the parsers are in a different package than the classes themselves, however, the only access possibility we have is public. So without friend functions, we really need to keep everything so closely related together in the same package, so we can use package protection for those special cases.