so

xml-apis.jar? 😕 🤬 🤢

Volume 7, Issue 19; 17 Feb 2023

Cursory archeology on my least favorite XML-related Maven dependency.

Lots of XML-related projects on the JVM depend on some version of xml-apis.jar. This is usually expressed as a dependency. For example, Jing-Trang, declares:

<dependency groupId="xml-apis" artifactId="xml-apis" version="1.0.b2"/>

Last time I went down this path trying to figure out “what version should I depend on,” I settled on 1.4.01. I think I settled on that because it appeared to be the most recent version compatible with other versions used by other tools libraries I depend on.

Why do I care? One aspect of the dependency hell problem is conflicting dependencies. If I depend on A.jar that depends on X.jar version 3.4 and on B.jar that depends on X.jar version 3.7, what happens? “That depends.” (Hahaha) If versions 3.4 and 3.7 are really incompatible, that’s real trouble. If they are at least compatible, which version you get depends on how the classpath is resolved. If B.jar really needs version 3.7 and 3.4 gets loaded first, your program will probably crash. If 3.7 is loaded first, and A.jar is ok with 3.7, things will be fine. If which version gets loaded is unpredicable, that’s hellish.

One way to attempt to mitigate this is to tell your build system to force a particular version regardless of what’s requested. Hence, I want to know what’s the “best” version.

As far as I can tell from metadata, this collection of APIs started out as part of the xml-commons at Apache as the XML Commons External Components XML APIs. Let me say up front that I’m not trying to cast aspersions in that team or that project. This probably all made more sense back in the day, it’s trying to work it out from here that’s frustrating.

What are our choices? According to Maven Central:

Version Release date Dependents
2.0.2 2005-11-19 1,217
2.0.0 2005-11-19 1
1.0.b2 2007-02-09 1,715
1.3.02 2005-11-19 656
1.3.03 2006-05-12 432
1.3.04 2006-12-22 2,382
1.2.01 2010-02-03 0
1.4.01 2011-08-20 22,028

Sorted by release date, things already look a bit funny. So, what’s in these releases?

Version Binaries Source JavaDoc
1.0.b2
1.2.01
1.3.02
1.3.03
1.3.04
1.4.01
2.0.0
2.0.2

Version 1.2.01 stands out right way. It’s just a Maven POM file. The POM file (I’m no expert on Maven, so take my remarks about it with a grain if salt) says it’s been relocated to xerces:xmlParserAPIs:2.6.2. In other words, if you want 1.2.01, you don’t reall want that, you want the Xerces xmlParserAPIs version 2.6.2.

As long as we’re dealing with relocations, let’s talk about 2.0.0 and 2.0.2: although they contain binaries of their own, they claim to be relocated to 1.0.b2. I don’t really understand what that means.

And finally, in the distributionManagement section of their POM files, 1.3.02 and 1.3.03 claim to have downloadUrl s that point to Xerces-J-bin.2.7.1.tar.gz and Xerces-J-bin.2.8.0.tar.gz, respectively. I don’t understand that either.

So how similar are these versions? Let’s just do a little spot checking. What do we find if we compare 1.0.b2 with 1.2.01 (which is really Xerces xmlParserAPIs version 2.6.2):

$ zipdiff xml-apis-1.0.b2.jar xmlParserAPIs-2.6.2.jar | grep -v \\$
Missing from xmlParserAPIs-2.6.2.jar:
	license/LICENSE.txt
	license/README.txt
	org/w3c/dom/html/HTMLBlockquoteElement.class

New in xmlParserAPIs-2.6.2.jar:
	javax/xml/parsers/FilePathToURI.class
	javax/xml/parsers/SecuritySupport.class
	javax/xml/parsers/SecuritySupport12.class
	javax/xml/transform/SecuritySupport.class
	javax/xml/transform/SecuritySupport12.class
	javax/xml/transform/stream/FilePathToURI.class
	org/xml/sax/helpers/SecuritySupport.class
	org/xml/sax/helpers/SecuritySupport12.class

It’s not backwards compatible because the HTMLBlockquoteElement is missing, but maybe that’s not too serious. What about from 1.2.01 to 1.3.02?

$ zipdiff xmlParserAPIs-2.6.2.jar  xml-apis-1.3.02.jar | grep -v \\$
Missing from xml-apis-1.3.02.jar:
	javax/xml/parsers/SecuritySupport12.class
	javax/xml/transform/SecuritySupport12.class

New in xml-apis-1.3.02.jar:
	javax/xml/XMLConstants.class
	javax/xml/datatype/
	javax/xml/datatype/DatatypeConfigurationException.class
	javax/xml/datatype/DatatypeConstants.class
	javax/xml/datatype/DatatypeFactory.class
	javax/xml/datatype/Duration.class
	javax/xml/datatype/FactoryFinder.class
	javax/xml/datatype/SecuritySupport.class
	javax/xml/datatype/XMLGregorianCalendar.class
	javax/xml/namespace/
	javax/xml/namespace/NamespaceContext.class
	javax/xml/namespace/QName.class
	javax/xml/validation/
	javax/xml/validation/Schema.class
	javax/xml/validation/SchemaFactory.class
	javax/xml/validation/SchemaFactoryFinder.class
	javax/xml/validation/SecuritySupport.class
	javax/xml/validation/TypeInfoProvider.class
	javax/xml/validation/Validator.class
	javax/xml/validation/ValidatorHandler.class
	javax/xml/xpath/
	javax/xml/xpath/SecuritySupport.class
	javax/xml/xpath/XPath.class
	javax/xml/xpath/XPathConstants.class
	javax/xml/xpath/XPathException.class
	javax/xml/xpath/XPathExpression.class
	javax/xml/xpath/XPathExpressionException.class
	javax/xml/xpath/XPathFactory.class
	javax/xml/xpath/XPathFactoryConfigurationException.class
	javax/xml/xpath/XPathFactoryFinder.class
	javax/xml/xpath/XPathFunction.class
	javax/xml/xpath/XPathFunctionException.class
	javax/xml/xpath/XPathFunctionResolver.class
	javax/xml/xpath/XPathVariableResolver.class
	license/LICENSE
	license/NOTICE
	org/w3c/dom/DOMConfiguration.class
	org/w3c/dom/DOMError.class
	org/w3c/dom/DOMErrorHandler.class
	org/w3c/dom/DOMImplementationList.class
	org/w3c/dom/DOMImplementationSource.class
	org/w3c/dom/DOMLocator.class
	org/w3c/dom/DOMStringList.class
	org/w3c/dom/NameList.class
	org/w3c/dom/TypeInfo.class
	org/w3c/dom/UserDataHandler.class
	org/w3c/dom/bootstrap/
	org/w3c/dom/bootstrap/DOMImplementationRegistry.class
	org/w3c/dom/ls/
	org/w3c/dom/ls/DOMImplementationLS.class
	org/w3c/dom/ls/LSException.class
	org/w3c/dom/ls/LSInput.class
	org/w3c/dom/ls/LSLoadEvent.class
	org/w3c/dom/ls/LSOutput.class
	org/w3c/dom/ls/LSParser.class
	org/w3c/dom/ls/LSParserFilter.class
	org/w3c/dom/ls/LSProgressEvent.class
	org/w3c/dom/ls/LSResourceResolver.class
	org/w3c/dom/ls/LSSerializer.class
	org/w3c/dom/ls/LSSerializerFilter.class
	org/w3c/dom/xpath/
	org/w3c/dom/xpath/XPathEvaluator.class
	org/w3c/dom/xpath/XPathException.class
	org/w3c/dom/xpath/XPathExpression.class
	org/w3c/dom/xpath/XPathNSResolver.class
	org/w3c/dom/xpath/XPathNamespace.class
	org/w3c/dom/xpath/XPathResult.class
	org/xml/sax/ext/Attributes2.class
	org/xml/sax/ext/Attributes2Impl.class
	org/xml/sax/ext/DefaultHandler2.class
	org/xml/sax/ext/EntityResolver2.class
	org/xml/sax/ext/Locator2.class
	org/xml/sax/ext/Locator2Impl.class

Okay, we’ve added a bunch of APIs. I don’t know if losing the “security support” classes is a problem or not.

Versions 1.3.02 and 1.3.03 are the same. Version 1.3.04 adds a SchemaFactoryLoader and, curiously, a completely empty org.w3c.css package.

$ zipdiff xml-apis-1.3.03.jar xml-apis-1.3.04.jar | grep -v \\$
New in xml-apis-1.3.04.jar:
	javax/xml/validation/SchemaFactoryLoader.class
	org/w3c/css/

Version 1.4.01 loses another “security support” class and gains the streaming API:

$ zipdiff xml-apis-1.3.04.jar xml-apis-1.4.01.jar | grep -v \\$
Missing from xml-apis-1.4.01.jar:
	org/xml/sax/helpers/SecuritySupport12.class

New in xml-apis-1.4.01.jar:
	javax/xml/stream/
	javax/xml/stream/EventFilter.class
	javax/xml/stream/FactoryConfigurationError.class
	javax/xml/stream/FactoryFinder.class
	javax/xml/stream/Location.class
	javax/xml/stream/SecuritySupport.class
	javax/xml/stream/StreamFilter.class
	javax/xml/stream/XMLEventFactory.class
	javax/xml/stream/XMLEventReader.class
	javax/xml/stream/XMLEventWriter.class
	javax/xml/stream/XMLInputFactory.class
	javax/xml/stream/XMLOutputFactory.class
	javax/xml/stream/XMLReporter.class
	javax/xml/stream/XMLResolver.class
	javax/xml/stream/XMLStreamConstants.class
	javax/xml/stream/XMLStreamException.class
	javax/xml/stream/XMLStreamReader.class
	javax/xml/stream/XMLStreamWriter.class
	javax/xml/stream/events/
	javax/xml/stream/events/Attribute.class
	javax/xml/stream/events/Characters.class
	javax/xml/stream/events/Comment.class
	javax/xml/stream/events/DTD.class
	javax/xml/stream/events/EndDocument.class
	javax/xml/stream/events/EndElement.class
	javax/xml/stream/events/EntityDeclaration.class
	javax/xml/stream/events/EntityReference.class
	javax/xml/stream/events/Namespace.class
	javax/xml/stream/events/NotationDeclaration.class
	javax/xml/stream/events/ProcessingInstruction.class
	javax/xml/stream/events/StartDocument.class
	javax/xml/stream/events/StartElement.class
	javax/xml/stream/events/XMLEvent.class
	javax/xml/stream/util/
	javax/xml/stream/util/EventReaderDelegate.class
	javax/xml/stream/util/StreamReaderDelegate.class
	javax/xml/stream/util/XMLEventAllocator.class
	javax/xml/stream/util/XMLEventConsumer.class
	javax/xml/transform/stax/
	javax/xml/transform/stax/StAXResult.class
	javax/xml/transform/stax/StAXSource.class
	org/w3c/dom/ElementTraversal.class

Versions 2.0.0 and 2.0.2 are the same, but they’re wildly incompatible with 1.4.01:

$ zipdiff xml-apis-1.4.01.jar xml-apis-2.0.0.jar  | grep -v \\$
Missing from xml-apis-2.0.0.jar:
	javax/xml/XMLConstants.class
	javax/xml/datatype/
	javax/xml/datatype/DatatypeConfigurationException.class
	javax/xml/datatype/DatatypeConstants.class
	javax/xml/datatype/DatatypeFactory.class
	javax/xml/datatype/Duration.class
	javax/xml/datatype/FactoryFinder.class
	javax/xml/datatype/SecuritySupport.class
	javax/xml/datatype/XMLGregorianCalendar.class
	javax/xml/namespace/
	javax/xml/namespace/NamespaceContext.class
	javax/xml/namespace/QName.class
	javax/xml/parsers/FilePathToURI.class
	javax/xml/parsers/SecuritySupport.class
	javax/xml/stream/
	javax/xml/stream/EventFilter.class
	javax/xml/stream/FactoryConfigurationError.class
	javax/xml/stream/FactoryFinder.class
	javax/xml/stream/Location.class
	javax/xml/stream/SecuritySupport.class
	javax/xml/stream/StreamFilter.class
	javax/xml/stream/XMLEventFactory.class
	javax/xml/stream/XMLEventReader.class
	javax/xml/stream/XMLEventWriter.class
	javax/xml/stream/XMLInputFactory.class
	javax/xml/stream/XMLOutputFactory.class
	javax/xml/stream/XMLReporter.class
	javax/xml/stream/XMLResolver.class
	javax/xml/stream/XMLStreamConstants.class
	javax/xml/stream/XMLStreamException.class
	javax/xml/stream/XMLStreamReader.class
	javax/xml/stream/XMLStreamWriter.class
	javax/xml/stream/events/
	javax/xml/stream/events/Attribute.class
	javax/xml/stream/events/Characters.class
	javax/xml/stream/events/Comment.class
	javax/xml/stream/events/DTD.class
	javax/xml/stream/events/EndDocument.class
	javax/xml/stream/events/EndElement.class
	javax/xml/stream/events/EntityDeclaration.class
	javax/xml/stream/events/EntityReference.class
	javax/xml/stream/events/Namespace.class
	javax/xml/stream/events/NotationDeclaration.class
	javax/xml/stream/events/ProcessingInstruction.class
	javax/xml/stream/events/StartDocument.class
	javax/xml/stream/events/StartElement.class
	javax/xml/stream/events/XMLEvent.class
	javax/xml/stream/util/
	javax/xml/stream/util/EventReaderDelegate.class
	javax/xml/stream/util/StreamReaderDelegate.class
	javax/xml/stream/util/XMLEventAllocator.class
	javax/xml/stream/util/XMLEventConsumer.class
	javax/xml/transform/SecuritySupport.class
	javax/xml/transform/stax/
	javax/xml/transform/stax/StAXResult.class
	javax/xml/transform/stax/StAXSource.class
	javax/xml/transform/stream/FilePathToURI.class
	javax/xml/validation/
	javax/xml/validation/Schema.class
	javax/xml/validation/SchemaFactory.class
	javax/xml/validation/SchemaFactoryFinder.class
	javax/xml/validation/SchemaFactoryLoader.class
	javax/xml/validation/SecuritySupport.class
	javax/xml/validation/TypeInfoProvider.class
	javax/xml/validation/Validator.class
	javax/xml/validation/ValidatorHandler.class
	javax/xml/xpath/
	javax/xml/xpath/SecuritySupport.class
	javax/xml/xpath/XPath.class
	javax/xml/xpath/XPathConstants.class
	javax/xml/xpath/XPathException.class
	javax/xml/xpath/XPathExpression.class
	javax/xml/xpath/XPathExpressionException.class
	javax/xml/xpath/XPathFactory.class
	javax/xml/xpath/XPathFactoryConfigurationException.class
	javax/xml/xpath/XPathFactoryFinder.class
	javax/xml/xpath/XPathFunction.class
	javax/xml/xpath/XPathFunctionException.class
	javax/xml/xpath/XPathFunctionResolver.class
	javax/xml/xpath/XPathVariableResolver.class
	license/LICENSE
	license/NOTICE
	org/w3c/css/
	org/w3c/dom/DOMConfiguration.class
	org/w3c/dom/DOMError.class
	org/w3c/dom/DOMErrorHandler.class
	org/w3c/dom/DOMImplementationList.class
	org/w3c/dom/DOMImplementationSource.class
	org/w3c/dom/DOMLocator.class
	org/w3c/dom/DOMStringList.class
	org/w3c/dom/ElementTraversal.class
	org/w3c/dom/NameList.class
	org/w3c/dom/TypeInfo.class
	org/w3c/dom/UserDataHandler.class
	org/w3c/dom/bootstrap/
	org/w3c/dom/bootstrap/DOMImplementationRegistry.class
	org/w3c/dom/ls/
	org/w3c/dom/ls/DOMImplementationLS.class
	org/w3c/dom/ls/LSException.class
	org/w3c/dom/ls/LSInput.class
	org/w3c/dom/ls/LSLoadEvent.class
	org/w3c/dom/ls/LSOutput.class
	org/w3c/dom/ls/LSParser.class
	org/w3c/dom/ls/LSParserFilter.class
	org/w3c/dom/ls/LSProgressEvent.class
	org/w3c/dom/ls/LSResourceResolver.class
	org/w3c/dom/ls/LSSerializer.class
	org/w3c/dom/ls/LSSerializerFilter.class
	org/w3c/dom/xpath/
	org/w3c/dom/xpath/XPathEvaluator.class
	org/w3c/dom/xpath/XPathException.class
	org/w3c/dom/xpath/XPathExpression.class
	org/w3c/dom/xpath/XPathNSResolver.class
	org/w3c/dom/xpath/XPathNamespace.class
	org/w3c/dom/xpath/XPathResult.class
	org/xml/sax/ext/Attributes2.class
	org/xml/sax/ext/Attributes2Impl.class
	org/xml/sax/ext/DefaultHandler2.class
	org/xml/sax/ext/EntityResolver2.class
	org/xml/sax/ext/Locator2.class
	org/xml/sax/ext/Locator2Impl.class
	org/xml/sax/helpers/SecuritySupport.class

New in xml-apis-2.0.0.jar:
	license/LICENSE.txt
	license/README.txt
	org/w3c/dom/html/HTMLBlockquoteElement.class

They are, I guess we should be glad, compatible with 1.0.b2 which they claim to be relocated to!

What does this tell us? I’m not sure I know. But at least next time I 🤬 about some weird bug that’s possibly related to the version of xml-apis.jar I’ll know where I wrote it all down.

And I think I’ve reassured myself that 1.4.01 is the right choice.

#Java #XML