Ionut
Ionut

Reputation: 113

xsd conflict when using jaxb2-maven-plugin

I'm trying to revive a legacy project for my client. The project is pretty old and it uses the jaxb2-maven-plugin to generate some java classes from an xsd schema file.

   <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>jaxb2-maven-plugin</artifactId>
      <version>2.4</version>
      <executions>
         <execution>
            <goals>
               <goal>xjc</goal>
            </goals>
         </execution>
      </executions>
      <configuration>
         <sources>
            <source>src/main/resources/custom-api.xsd</source>
         </sources>
         <packageName>com.client</packageName>
         <catalog>src/main/resources/catalog.cat</catalog>
      </configuration>
   </plugin>

The problem is the company doesn't allow any internet access - hence when I generate the code I get errors such as java.net.UnknownHostException saying that it cannot find www.springframework.org.

So I understand that the solution for this problem is to provide the xsd files locally - which I did, extracting them in a folder named import and I created also a catalog.cat file to rewrite the access to those xsd files to the import folder.

The catalog.cat file looks like this:

REWRITE_SYSTEM "http://www.springframework.org/schema/beans/spring-beans-3.1.xsd" "import/spring-beans-3.1.xsd"
REWRITE_SYSTEM "http://www.mulesoft.org/schema/mule/core/3.4/mule.xsd" "import/mule.xsd"
REWRITE_SYSTEM "http://www.mulesoft.org/schema/mule/schemadoc/3.4/mule-schemadoc.xsd" "import/mule-schemadoc.xsd"
REWRITE_SYSTEM "http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd" "import/mule-jms.xsd"
REWRITE_SYSTEM "http://www.springframework.org/schema/context/spring-context-3.1.xsd" "import/spring-context-3.1.xsd"
REWRITE_SYSTEM "http://www.springframework.org/schema/tool/spring-tool-3.1.xsd" "import/spring-tool-3.1.xsd"

Unfortunately I get some conflicts in spring-beans.xsd:

com.sun.istack.SAXParseException2publicId: http://www.springframework.org/schema/beans; systemId: http://www.springframework.org/schema/beans/spring-beans-3.1.xsd; lineNumber: 566; columnNumber: 30; Property "Ref" is already defined. Use &lt;jaxb:property> to resolve this conflict.
                at com.sun.tools.xjc.ErrorReceiver.error(ErrorReceiver.java:56)

I suspect that this happens because the xsd is loaded multiple times - probably being referenced by other xsd files. The usual way to get rid of such conflicts is to use a binding file, but I don't think this is the right thing to do considering that this is a third party xsd file.

An example of a sample project has been provided here: https://github.com/scutaru/sample-xjc

Anybody knows how I can get rid of these conflicts ?

Upvotes: 1

Views: 673

Answers (1)

Laurent Schoelens
Laurent Schoelens

Reputation: 2848

I've downloaded your project sample (thanks for it by the way)

  • After upgrading to latest version of maven-jaxb2-plugin with new coordinates
<groupId>org.jvnet.jaxb</groupId>
<artifactId>jaxb-maven-plugin</artifactId>
<version>2.0.9</version>
  • And after updating your catalog to fix the public ref to namespace declaration
PUBLIC "http://www.springframework.org/schema/beans" "maven:org.springframework:spring-beans::!/org/springframework/beans/factory/xml/spring-beans-3.1.xsd"
PUBLIC "http://www.mulesoft.org/schema/mule/core" "maven:org.mule.modules:mule-module-spring-config:jar::!/META-INF/mule.xsd"
PUBLIC "http://www.mulesoft.org/schema/mule/schemadoc" "maven:org.mule.modules:mule-module-spring-config:jar::!/META-INF/mule-schemadoc.xsd"
PUBLIC "http://www.mulesoft.org/schema/mule/jms" "maven:org.mule.transports:mule-transport-jms:jar::!/META-INF/mule-jms.xsd"
PUBLIC "http://www.springframework.org/schema/context" "maven:org.springframework:spring-context::!/org/springframework/context/config/spring-context-3.1.xsd"
PUBLIC "http://www.springframework.org/schema/tool" "maven:org.springframework:spring-beans::!/org/springframework/beans/factory/xml/spring-tool-3.1.xsd"

I manage to reproduce your error

[ERROR] Error while parsing schema(s).Location [ http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/beans{566,30}].
com.sun.istack.SAXParseException2: Property "Ref" is already defined. Use &lt;jaxb:property> to resolve this conflict.
    at com.sun.tools.xjc.ErrorReceiver.error (ErrorReceiver.java:56)
[...]
[ERROR] Error while parsing schema(s).Location [ http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/beans{606,48}].
com.sun.istack.SAXParseException2: The following location is relevant to the above error

As you can see, the error is split in two parts, in order to know where the conflict is located. Here for example, you have the ref element that is declared twice in spring-beans.xsd (line 566 v. line 606).

By looking at the xsd, you'll find that constructor-arg xsd:element has two ref declared, one as child xsd:element and another one as xsd:attribute, documented as A short-cut alternative to a nested "<ref bean='...'/>" element.

In the end, your configuration is good but you need to apply the following trick that was mentionned in the comments.

Using the following bindings.xjb file, you should be able to generate your XSD :

<jaxb:bindings 
    version="2.1"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <jaxb:bindings xmlns:tns="http://www.springframework.org/schema/beans" scd="x-schema::tns">
        <jaxb:bindings scd="/tns:ref">
            <jaxb:property name="refAttribute"/>
        </jaxb:bindings>
        <jaxb:bindings scd="/tns:value">
            <jaxb:property name="valueAttribute"/>
        </jaxb:bindings>
        <jaxb:bindings scd="/tns:key">
            <jaxb:property name="keyAttribute"/>
        </jaxb:bindings>
    </jaxb:bindings>
    <jaxb:bindings xmlns:tns="http://www.springframework.org/schema/context" scd="x-schema::tns">
        <jaxb:bindings scd="/tns:property-placeholder">
            <jaxb:class name="org.springframework.schema.context.PropertyPlaceholderElement"/>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

Upvotes: 1

Related Questions