I recently ran into a problem with a customer’s Java environment where some of the classes that PDF OCR X requires were being overridden by out-of-date classes. The error wasn’t exactly intuitive:
java.lang.AbstractMethodError: java.lang.AbstractMethodError: javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
This was happening when I was trying to parse an XML document, and it only happened on this one customer’s machine. The problem was that he had an old version of Xerces installed in one of his Java extensions directory. He had probably installed it there years ago (or a program did it for him) as a shortcut to make sure that Xerces was always available without having to add it to the classpath for each project. Whatever the reason, it was causing problems for me in present day.
I actually include my own copy of Xerces as part of the application and it is included in the classpath. So shouldn’t that override any jars in the system extensions directory?
Java will look first in the bootstrap files, then in the extensions directory for classes. And finally, it will look in your classpath only if it can’t find the class in one of the first two places.
This means that it is a really bad idea to add libraries to the Java extensions directories unless you are willing to keep them up to date. You may have problems down the road, and they might not be easy to solve.
This reminds me of a current discussion on the Mac Java development mailing list regarding the pros and cons of bundling your own Java runtime when you distribute applications. If you do decide to rely on the system’s runtime, you are at the mercy of the user’s environment. They can break your application in a thousand different ways by installing old, broken, and dirty libraries into their extensions directories.
Best practice: If Oracle or Apple doesn’t put something in the extensions directory, then you shouldn’t either. Period.