What Version of Xerces are you Using?
XML developers often find themselves struggling with multiple versions of the Xerces parser for Java which support different, slightly incompatible versions of SAX, DOM, Schemas, and even XML itself. Xerces can be hiding in a number of different places including the classpath, the jre/lib/endorsed directory, and even the JDK itself. Here’s how you can find out which version you actually have.
First, from the command line, try this:
$ java -org.apache.xerces.impl.Version Xerces-J 2.8.0
If that fails:
$ java org.apache.xerces.impl.Version Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/xerces/impl/Version
Then point the classpath at the jar file you’re loading:
$ java -classpath dtd-xercesImpl.jar org.apache.xerces.impl.Version Xerces-J 2.8.0
If you don’t have a Xerces jar in your classpath, then if you’re using Java 5 or later, you likely have the version of Xerces bundled with the JDK. Check its version thusly:
$ java com.sun.org.apache.xerces.internal.impl.Version Xerces-J 2.6.2
Finally, if you need to find out from within your source code, you invoke the static Version.getVersion()
method like so:
String xercesVersion = Version.getVersion();
For comparisons–e.g. to see if you have Xerces version 2.6.1 or later–this simple bit of code will convert most version strings. including Xerces’s, to a decimal value:
public static double toDouble(String s) {
try {
return Double.parseDouble(s);
}
catch (NumberFormatException ex) {
s = removeExtraPeriods(s);
return Double.parseDouble(s);
}
}
private static String removeExtraPeriods(String s) {
boolean decimalPointSeen = false;
StringBuffer result = new StringBuffer(s.length());
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= '0' && c <= '9') result.append(c);
else if (c == '.' && !decimalPointSeen) {
result.append(c);
decimalPointSeen = true;
}
}
return result.toString();
}
This covers most version string formats. I’ll leave it as an exercise for the reader to extend it to handle cases like comparing 2.6.2 to 2.6.2b.
Incidentally, the same tricks work for Xalan. You just have to point to org.apache.xalan.Version
instead of org.apache.xerces.impl.Version
:
$ java -classpath xalan.jar org.apache.xalan.Version
Xalan Java 2.7.0
April 1st, 2008 at 11:16 am
Doesn’t SomeXercesClass.class.getPackage.getImplementationVersion() work in code too? I thought their manifests were pretty good. That technique is a little more general because it’ll work for any well packaged Java library that has a good Manifest.
Depressingly few do though.
April 8th, 2008 at 1:35 am
I thought I’d point out that this conversion routine / comparison method will start to break down with the next major version: 2.10.0. The double value you’ll get after removing the extra decimal point will be the same as the 2.1.0 release so will appear to be “older” than Xerces-J 2.9.1.
December 20th, 2012 at 5:02 am
Thanks a lot for clarifying.