[jdom-interest] JDOM2 and Runtime Exceptions

Rolf Lear jdom at tuis.net
Tue Jan 17 19:31:10 PST 2012


Hi all.

Recent discussions have highlighted the area of how JDOM handles some 
exceptions. In particular the context was XPath expressions. JDOM 
specifies (and 'always' has specified) that XPath throws JDOMException 
in the event of a failure on XPath. This has been 'questioned' from the 
perspective that this would not be the fault of JDOM if the XPath 
expression failed to compile, or evaluate.

Exceptions that are outside the control of the programmer, like 
IOException, should be thrown and caught, but an illegal XPath is more 
of a bug/programming error than an Exception, and hence should be 
treated more like a NullPointerException, IllegalArgumentException, 
IndexOutOfBoundsException, etc.

Certainly it is 'ugly' to have to try/catch even the simplest XPath 
expressions:

List<?> nodes = null;
try {
   nodes = XPath.selectNodes(document, "//tag");
} catch (JDOMException e) {
   // handle it somehow
   ...
}
// do something with nodes.

This would all be much simpler if the code throws a RuntimeException 
instead:

List<?> nodes = XPath.selectNodes(document, "//tag");



So, having used XPath as one example, I can then extrapolate the issue 
in to other general areas (sticking with concepts that are 'old' - in 
JDOM as well as JDOM2 - JDOM2 has additional areas of concern):
1. SAXOutputter throws JDOMExcepion on all it's calls because it traps 
SAXException from the output target: 
http://jdom.org/docs/apidocs/org/jdom/output/SAXOutputter.html#output%28org.jdom.Document%29
2. DOMOutputter throws JDOMException to wrap 
ParserConfigurationException from Java's DocumentBuilder.
3. XSLTransform throws a subclass of JDOMException.

Interestingly, XMLOutputter throws IOException, but not JDOMException.


Taking the issue to an abstract level, there are a number of places 
where JDOM throws the checked exception JDOMException, and that 
exception requires cumbersome handling in situations where unchecked 
exceptions would (potentially) be a better choice.


There are a number issues at stake here though:

1. In JDOM the JDOMException is specified ( 
http://jdom.org/docs/apidocs/org/jdom/JDOMException.html ) as being the 
'top level Exception JDOM classes can throw'. But that's already *not* 
true. We have had all sorts of runtime exceptions thrown from various 
classes like 'Element' which throws IlleglNameException from it's 
constructor... So, should JDOMException be redefined to be JDOM-specific 
problems only?

2. Where is the 'line'? Should SAXOutputter throw SAXException instead 
of JDOMException (like XMLOutputter throws IOException not 
JDOMException)? Should SAXOutputter throw some new RuntimeException 
instead? How could the 'system' be described so that this inconsistency 
of exceptions is better controlled?

3. It creates a major backward-compatibility issue to remove the 'throws 
JDOMException' from methods. Existing code that does:

try {
   nodes = XPath.selectNodes(document, "//tag");
} catch (JDOMException jde) {
   // handle it somehow
   ...
}

Fails to compile with:

     [javac] 
....\src\java\org\jdom2\test\cases\xpath\AbstractTestXPath.java:595: 
exception org.jdom2.JDOMException is never thrown in body of 
corresponding try statement
     [javac] 		} catch (JDOMException jde) {
     [javac] 		  ^
     [javac] 1 error




I have been playing with the code anyway, and I like the looks of the 
results of replacing 'strategic' JDOMExceptions with a runtime 
Exception. For example, I created a new unchecked JDOMRuntimeException 
class. From this class I created two subclasses: XPathCompileException 
and XPathEvaluationException. I made all the code 'work' nicely with 
these exceptions and the code looks very clean.

Backward compatibility is 'screwed' though, but somewhat mitigated by 
the fact that 'old' code can be modified from:

    ...
} catch (JDOMException jde) {
    ...


to

    ...
} catch (JDOMRuntimeException jde) {
    ...

Alternatively, depending on the actual exception handling, the try/catch 
can be completely removed and handling can be cascaded up to a higher 
point....


Apart from renaming all the packages to org.jdom2, this would be the 
most significant migration problem for any users of JDOM/JDOM2. 
Documenting it as a migration issue should be relatively easy, but the 
fix would not be a pure search/replace, but the exceptions would have to 
be identified and fixed individually.

Admittedly in a tool like eclipse, it is quite easy to put 'Runtime' in 
your copy/paste buffer, and go from one compile problem to the next 
simply looking for the 'unreachable code' problem and adding the 
'Runtime' to the middle of 'JDOMException'.



Sorry for the long mail, but this is a 'feature' which could make JDOM2 
much easier to work with, but would certainly make a migration from JDOM 
more complicated.


Would love some thoughts on this....

Rolf


More information about the jdom-interest mailing list