1
votes

I have a Maven project with 3 modules: schema, gml and adress. schema contains two XSDs: gmlprofil-1.1.xsd - a simple GML profile and adress.xsd which imports the GML schema using a relative schemaLocation, like so:

<import schemaLocation="../gml/gmlprofil-1.1.xsd" namespace="http://www.opengis.net/gml/3.2"/>

In both the gml module and the adress module, I use maven-jaxb2-plugin with jaxb2-basics in order to generate classes with equals() and hashCode(). The gml module works fine, but when running adress, I get this error:

com.sun.istack.SAXParseException2; IOException thrown when processing "../gml/gmlprofil-1.1.xsd". Exception: java.io.FileNotFoundException: C:\code\gml\gmlprofil-1.1.xsd

Fine. A catalog file to the rescue!

REWRITE_SYSTEM "../gml/gmlprofil-1.1.xsd" "maven:com.test:schema:jar::!/com/test/schemas/gml/gmlprofil-1.1.xsd"

It looks like the absolute path is resolved OK, but then a MalformedURLException occurs.

[DEBUG] Parent resolver has resolved publicId [null], systemId [../gml/gmlprofil-1.1.xsd] to [maven:com.test:schema:jar::!/com/test/schemas/gml/gmlprofil-1.1.xsd].
[DEBUG] Resolving systemId [maven:com.test:schema:jar::!/com/test/schemas/gml/gmlprofil-1.1.xsd] as Maven dependency resource.
[DEBUG] Resolved dependency resource [Dependency {groupId=com.test, artifactId=schema, version=1.0-SNAPSHOT, type=jar, classifier=null, resource=com/test/schemas/gml/gmlprofil-1.1.xsd}] to resource URL [jar:file:/C:/code/jaxb-test/schema/target/schema-1.0-SNAPSHOT.jar!/com/test/schemas/gml/gmlprofil-1.1.xsd].
[DEBUG] Resolved systemId [maven:com.test:schema:jar::!/com/test/schemas/gml/gmlprofil-1.1.xsd] to [jar:file:/C:/code/jaxb-test/schema/target/schema-1.0-SNAPSHOT.jar!/com/test/schemas/gml/gmlprofil-1.1.xsd].
[ERROR] Error while parsing schema(s).Location [ maven:com.test:schema:jar::!/com/test/schemas/adress/adress.xsd{8,97}].
org.xml.sax.SAXParseException; systemId: maven:com.test:schema:jar::!/com/test/schemas/adress/adress.xsd; lineNumber: 8; columnNumber: 97; unknown protocol: maven
...
Caused by: java.net.MalformedURLException: unknown protocol: maven

This is my pom for adress:

  <plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.13.0</version>
    <executions>
      <execution>
        <phase>generate-sources</phase>
        <goals>
          <goal>generate</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <bindingDirectory>src/main/resources</bindingDirectory>
      <episode>true</episode>
      <useDependenciesAsEpisodes>true</useDependenciesAsEpisodes>
      <extension>true</extension>
      <forceRegenerate>false</forceRegenerate>
      <schemaLanguage>XMLSCHEMA</schemaLanguage>
      <strict>false</strict>
      <verbose>false</verbose>
      <catalog>src/main/resources/catalog.cat</catalog>
      <args>
        <arg>-npa</arg>
        <arg>-XsimpleEquals</arg>
        <arg>-XsimpleHashCode</arg>
      </args>
      <plugins>
        <plugin>
          <groupId>org.jvnet.jaxb2_commons</groupId>
          <artifactId>jaxb2-basics</artifactId>
          <version>0.9.5</version>
        </plugin>
      </plugins>
      <schemas>
        <schema>
          <dependencyResource>
            <groupId>com.test</groupId>
            <artifactId>schema</artifactId>
            <resource>com/test/schemas/adress/adress.xsd</resource>
          </dependencyResource>
        </schema>
      </schemas>
    </configuration>
  </plugin>

I have tried some solutions:

  1. Setting the Maven URL as the schemaLocation:
<import schemaLocation="maven:com.test:schema:jar::!/com/test/schemas/gml/gmlprofil-1.1.xsd" namespace="http://www.opengis.net/gml/3.2"/>
  1. Setting an absolute schemaLocation and updating the catalog file accordingly:
<import schemaLocation="http://test.com/schemas/gml/gmlprofil-1.1.xsd" namespace="http://www.opengis.net/gml/3.2"/>

REWRITE_SYSTEM "http://test.com/schemas" "maven:com.test:schema:jar::!/com/test/schemas"
  1. Lowering the maven-jaxb2-plugin version to 0.9.1. Using this method, I don't even need a catalog file, however I get this error instead:

    [ERROR] Failed to execute goal org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.9.1:generate (default) on project adress: Execution default of goal org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.9.1:generate failed: A required class was missing while executing org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.9.1:generate: com/sun/tools/xjc/model/Aspect

    This can be resolved by swapping in -Xequals and -XhashCode instead of -XsimpleEquals and -XsimpleHashCode.

All three solutions work, but none is perfect. The first two require manipulating the schema, while the third introduces an unwanted dependency on jaxb2-basics-runtime in the generated classes. The latter is acceptable but I would greatly appreciate it if anyone knows how to run simpleEquals with my setup.

1
A test project can be found here.aznan

1 Answers

2
votes

Well, welcome to my world of pain.

You're surely aware of the ogc-schema project, right?

The interesting part is actually that catalog even seems to resolved correctly. Not sure what's happening there but here's the solution I've finally found out to work best:

  • Compile the absolute URL:

            <schemas>
                <schema>
                    <url>http://test.com/schemas/adres/adres.xsd</url>
                </schema>
            </schemas>
    
  • Use a catalog to rewrite

    REWRITE_SYSTEM "http://test.com/schemas" "maven:com.test:schema:jar::!/com/test/schemas"

This is basicallyyour third solution but you don't have to change the schema. Just start from an absolute URL, it will be rewritten by the catalog.

Ah, yes:

DISCLAIMER I'm the author of , as well as the ogc-schema project mentioned above.

By the way, what's so bad about the jaxb2-basics-runtime dependency?