views:

1295

answers:

1

We are using JAXB 2.x to generate data objects from a massive schema system (42 XSD files). That entire process runs fine, no problems there. But they deprecated (and removed from implementation) the entire JAXB validation framework, replacing it with the JAXP validation framework instead. (This is all located in the javax.xml.validation package.)

I have all the files given in dependency order to the javax.xml.validation.SchemaFactory, and have verified that they are in the correct order. The problem is that one file is generating errors about not knowing references from a namespace defined in another file. It's basically acting like the import is failing. (I'm not entirely sure because, according to the XML Schema specification, a failed import is not an error. So I cannot verify that the import is failing; it generates no warnings or errors. Doesn't that blow your mind?) I know what file this is happening in, because if I comment out a reference, it stops complaining. Here's the basic code:

import javax.xml.transform.Source;

final java.util.ArrayList<Source> xsdSources =
    new java.util.ArrayList<Source>();
/* POPULATE THE LIST WITH ALL THE XSDS IN DEPENDENCY ORDER.
   THAT IS, FILES WITH NO DEPENDENCIES APPEAR IN LOWER INDEX.
   I USE javax.xml.transform.stream.StreamSource, GIVING IT
   STREAMS FROM java.util.jar.JarFile#getInputStream(JarEntry). */

final javax.xml.validation.SchemaFactory schemaFactory =
    javax.xml.validation.SchemaFactory.newInstance(
        javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
schemaFactory.setErrorHandler(new SchemaErrorHandler());
return schemaFactory.newSchema(xsdSources.toArray(new Source[]{}));

The only errors given by the error handler are those indicating that the references are not found. Here's what the XSD dependency list looks like for the files in question:

xsds/import/foo/thing.xsd (<xsd:element name="thing">...</xsd:element>)
xsds/import/foo/otherthing.xsd (<xsd:include schemaLocation="thing.xsd"/>)
xsds/import/foo/all.xsd (<xsd:include schemaLocation="otherthing.xsd"/>)
xsds/mystuff/main.xsd (<xsd:import namespace="foonamespace" schemaLocation="../import/foo/all.xsd/>)

The main.xsd file has lines like this, that throw up errors about unknown references:

<xsd:element xmlns:foo="foonamespace" ref="foo:thing"/>

The errors and stacktraces look like this:

org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name 'foo:thing' to a(n) 'element declaration' component.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:131)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:384)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(XSDHandler.java:2537)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(XSDHandler.java:2528)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getGlobalDecl(XSDHandler.java:1472)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseLocal(XSDElementTraverser.java:160)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.traverseLocalElements(XSDHandler.java:2049)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:582)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:552)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:519)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:485)
    at com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:210)

main.xsd does similar things for other files, in almost exactly the same way, and they all work fine. Any idea why this particular one might be giving errors?

A: 

Does the source that you are creating from java.util.jar.JarFile#getInputStream(JarEntry) have a base URL such that the relative URLs in your schemas can be resolved and are all of your schemas in the same JAR?

Have you tried doing it on the file system? If it works from the file system or an exploded classpath, try referring to my answer to another question for details about how to make it work from inside of a JAR.

DavidValeri
It works fine for other files, all of which are accessed the exact same way. So I don't think this is a URL vs. File System issue.
jdmichal
Back from the dead...I see you are using includes and imports. Are the target namespaces in the XSDs using the includes all the same? Also, it might be good to throw a breakpoint into the bundled Xerces code to see what is really going on. Have you tried validating your schemas with XSV or another third-party tool?
DavidValeri