The pain of over abstraction

While playing around with groovy it becomes painfully obvious how Java classes are often way too hard to use in a scripting context. Here's an example that uses Groovy to parse an XML file using Saxon and then run an XPath query against it.


#!/usr/bin/env groovy

import net.sf.saxon.xpath.XPathEvaluator
import org.xml.sax.InputSource;
import javax.xml.transform.sax.SAXSource;
import java.io.File;

is = new InputSource(new File("config.xml").toURL().toString());
ss = new SAXSource(is);
xpe = new XPathEvaluator(ss);

results = xpe.evaluate("/blog/base-url");

for (result in results) {
    println(result.getStringValue())
}


  

Not too bad I guess and a hell of a lot better then straight Java, however, here's how you do the same thing in Python with libxml.


#!/usr/bin/env python

import libxml2

doc = libxml2.parseFile("config.xml")

results = doc.xpathEval("/blog/base-url")

for result in results:
        print result.content


  

The Python is vastly more direct and to the point, even in this simple example the Java API is saddled with way too much abstraction. This drives me insane with Java, you can of course wrap whatever you want to gloss over the abstractions, but I really don't get why API designers for Java so adamantly refuse to make the common cases easy. I was there once myself, I had a wee bit to do with creating the overly abstracted mess that is the XML:DB API. I regret that design every time I look at it. it could have been soooo much easier to use. Why isn't it? Ugg, who knows, maybe that wouldn't have been enough Java like.

Anyway, to reinforce the point that the problem is with the API designs, here' s the Groovy example re-implemented in Jython.


#!/usr/bin/env jython

from net.sf.saxon.xpath import XPathEvaluator
from org.xml.sax import InputSource;
from javax.xml.transform.sax import SAXSource;
from java.io import File;

input = InputSource(File("config.xml").toURL().toString())
ss = SAXSource(input)
xpe = XPathEvaluator(ss)

results = xpe.evaluate("/blog/base-url")

for result in results:
    print result.getStringValue()


  

You might complain that Saxon doesn't have the best API, but all the Java XPath tools are bad, most of them much worse. DOM4j is probably a little better then Saxon, but not substantially.

Looking at these APIs it's also obvious why so many programmers like to moan about how hard XML is. Who can blame them when it takes four classes from four different packages just to parse an XML file. We won't even talk about the W3C DOM. We also won't talk about the fact that the Groovy example hides the fact that those APIs throw checked exceptions.

Oh yeah, how about serializing a document back to text? With libxml it's just doc.serialize(). How do you do it with your Java API? Honestly, I really don't even know with Saxon, but I know it takes a hell of a lot more then one method call. It sure did when working with Xerces and I could never remember how to do it without looking it up.

I used to love Java, I also used to think Java was THE language for working with XML. I don't believe that anymore. Sure it's great to have an API that can have any individual component replaced, but that makes the API also have a massive barrier to actually writing code with it. Most Java APIs make the hard stuff possible, but they've really lost sight of the idea that the easy stuff should be easy.

Posted by Kimbro Staken

Tuesday Dec 2, 2003 at 2:16 PM
Recommended Sites