Michael Kay
Michael Kay

Reputation: 163302

Ant fails to locate XML catalog resolver

My Ant 1.8.2 build started failing with HTTP 303 responses from the W3C web site in response to requests for SVG DTDs. So I'm trying to introduce an XML Catalog to resolve them locally.

If I make no changes to the classpath, I get:

Warning: XML resolver not found; external catalogs will be ignored

If I add resolver.jar from Apache XML Commons 1.2 to the classpath (e.g. by using -lib on the ant invocation), I get

/Users/mike/..../build.xml:123: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.tools.ant.types.XMLCatalog$ExternalResolver.processExternalCatalogs(XMLCatalog.java:1115) at org.apache.tools.ant.types.XMLCatalog$ExternalResolver.resolveEntity(XMLCatalog.java:960) at org.apache.tools.ant.types.XMLCatalog.resolveEntity(XMLCatalog.java:391)

which suggests to me that the resolver.jar I am using has been located, but doesn't have the interface that Ant is expecting.

Where should I get the correct resolver.jar to use with Ant?

Upvotes: 2

Views: 2048

Answers (2)

Eero Helenius
Eero Helenius

Reputation: 2585

I had the same issue, but for me, the upgrading from Ant 1.8.1 to 1.9.4 solved the problem.

My guess is that the root cause is bug 52754.

EDIT: The same issue resurfaced in a slightly different form, using JDK 1.6.0_18, with a stack trace like this:

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.tools.ant.types.XMLCatalog$ExternalResolver.processExternalCatalogs(XMLCatalog.java:1116)
    at org.apache.tools.ant.types.XMLCatalog$ExternalResolver.resolve(XMLCatalog.java:1007)
    at org.apache.tools.ant.types.XMLCatalog.resolve(XMLCatalog.java:420)
    at net.sf.saxon.style.XSLGeneralIncorporate.getIncludedStylesheet(XSLGeneralIncorporate.java:104)
    at net.sf.saxon.style.XSLStylesheet.spliceIncludes(XSLStylesheet.java:754)
    at net.sf.saxon.style.XSLStylesheet.preprocess(XSLStylesheet.java:676)
    at net.sf.saxon.PreparedStylesheet.setStylesheetDocument(PreparedStylesheet.java:331)
    at net.sf.saxon.PreparedStylesheet.prepare(PreparedStylesheet.java:163)
    at net.sf.saxon.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:139)
    at org.apache.tools.ant.taskdefs.optional.TraXLiaison.readTemplates(TraXLiaison.java:300)
    at org.apache.tools.ant.taskdefs.optional.TraXLiaison.createTransformer(TraXLiaison.java:317)
    at org.apache.tools.ant.taskdefs.optional.TraXLiaison.transform(TraXLiaison.java:178)
    at org.apache.tools.ant.taskdefs.XSLTProcess.process(XSLTProcess.java:842)
    at org.apache.tools.ant.taskdefs.XSLTProcess.execute(XSLTProcess.java:432)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at org.apache.tools.ant.Target.performTasks(Target.java:456)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
    at org.apache.tools.ant.helper.SingleCheckExecutor.executeTargets(SingleCheckExecutor.java:38)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
    at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:441)
    at org.apache.tools.ant.taskdefs.CallTarget.execute(CallTarget.java:105)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at org.apache.tools.ant.Target.performTasks(Target.java:456)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
    at org.apache.tools.ant.Main.runBuild(Main.java:851)
    at org.apache.tools.ant.Main.startAnt(Main.java:235)
    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:1937)
    at java.lang.String.substring(String.java:1904)
    at org.apache.xml.resolver.helpers.PublicId.normalize(Unknown Source)
    at org.apache.xml.resolver.Catalog.addEntry(Unknown Source)
    at org.apache.tools.ant.types.resolver.ApacheCatalog.addEntry(ApacheCatalog.java:118)
    at org.apache.xml.resolver.readers.OASISXMLCatalogReader.startElement(Unknown Source)
    at org.apache.xml.resolver.readers.SAXCatalogReader.startElement(Unknown Source)
    at org.apache.xml.resolver.readers.SAXParserHandler.startElement(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(SAXParser.java:395)
    at org.apache.xml.resolver.readers.SAXCatalogReader.readCatalog(Unknown Source)
    at org.apache.xml.resolver.Catalog.parseCatalogFile(Unknown Source)
    at org.apache.xml.resolver.Catalog.parsePendingCatalogs(Unknown Source)
    at org.apache.xml.resolver.Catalog.parseCatalog(Unknown Source)
    at org.apache.tools.ant.types.resolver.ApacheCatalogResolver.parseCatalog(ApacheCatalogResolver.java:118)
 ... 47 more

Interestingly, the error only occurred on Windows and only sporadically, maybe one time out of seven or so.

The error originates in the normalize function of the PublicId class in the Apache Resolver library.

normal.indexOf(" ") would sometimes return the wrong value. For example, if the input string was -//OASIS//ELEMENTS DITA 1.x Programming Domain//EN, the pos variable would get 50 as its value, even though the public ID string has no extra spaces whatsoever.

That leads me to think that the root cause might be somehow related to JDK bug #6967156, but I can't be sure at all, since in our case, the error was intermittent, but nothing in the bug report suggests that.

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163302

I found the solution (well, a workaround...)

The InvocationTargetException turned out to be a red herring - a secondary error. The primary error was as follows: my catalog file catalog.xml contained a relative reference to a DTD catalog.dtd, and Ant (or the resolver) was failing to resolve the reference to catalog.dtd. It was looking in the directory containing my build file, not the directory containing the catalog. This is clearly a bug somewhere; my suspicion, if I were investigating further, would be that Ant is passing the catalog file to the catalog resolver with no base URI, or with an incorrect base URI, so the XML parser has to guess where to find the DTD, and guesses wrong.

My solution was to remove the reference to the DTD. After this, URIs listed in the catalog were correctly resolved to local copies. Interestingly, the references to local copies are also relative to the catalog, so it seems that the catalog resolver knows where the catalog is, but someone isn't telling Xerces at the time it is parsed.

Upvotes: 2

Related Questions