How to use a class customization to resolve file generating conflicts

54,214

Solution 1

The error message you are facing basically states that some names in the the typessection of your wsdl are you used two times. In your case all <element>tags have the same name as their corresponding types (defined as <complexType>).

Example:

  <s:element name="SearchFlights">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="SoapMessage" type="tns:SearchFlights" />
      </s:sequence>
    </s:complexType>
  </s:element>

  <s:complexType name="SearchFlights">
    <s:complexContent mixed="false">
      <s:extension base="tns:SoapMessageBase">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Request" type="tns:SearchFlightsRequest" />
          <s:element minOccurs="0" maxOccurs="1" name="Response" type="tns:SearchFlightsResponse" />
        </s:sequence>
      </s:extension>
    </s:complexContent>
  </s:complexType>

This is quite uncommon.

There are basically two options to resolve these issues:

Use autoNameResolution

 <plugin>
     <groupId>org.jvnet.jaxb2.maven2</groupId>
     <artifactId>maven-jaxb2-plugin</artifactId>
     <version>0.13.1</version>
     <executions>
         <execution>
             <goals>
                 <goal>generate</goal>
             </goals>
         </execution>
     </executions>
     <configuration>

         <args>
             <arg>-XautoNameResolution</arg>
         </args>

         <schemaLanguage>WSDL</schemaLanguage>
         <generatePackage>hello.wsdl</generatePackage>
         <schemas>
             <schema>
                 <url>http://www5v80.elsyarres.net/service.asmx?wsdl</url>
             </schema>
          </schemas>
      </configuration>
  </plugin>

The plugin will resolve all naming conflicts through appending numbers to every colliding name. In the above mentioned case of SearchFlights this will result in SearchFlights and SearchFlights2 being generated.

A better way would be to use a binding file to resolve all name conflicts in advance. Binding files mostly contain XPATHexpression and transformation rules. A binding file that appends to every declarations name is the following:

<?xml version="1.0" encoding="UTF-8"?>
<jaxws:bindings wsdlLocation="http://www5v80.elsyarres.net/service.asmx?wsdl"
            xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
            xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1"
            xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='ElsyArres.API']">
        <jaxb:schemaBindings>
            <jaxb:nameXmlTransform>
                <jaxb:elementName suffix="Elem"/>
            </jaxb:nameXmlTransform>
        </jaxb:schemaBindings>
    </jaxws:bindings>
</jaxws:bindings>

There are other options for jaxb:nameXmlTransform like suffixes and prepending to other kind of xml elements (like types).

Sadly i could not get to work this binding file with the org.jvnet.jaxb2.maven2:maven-jaxb2-plugin( but i am sure there is a working configuration)

It nevertheless works with the org.codehaus.mojo:jaxws-maven-plugin and the following configuration.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.4.1</version>
    <executions>
        <execution>
            <goals>
                <goal>wsimport</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <bindingFiles>
         <bindingFile>${basedir}/src/main/resources/bindings.xjb</bindingFile>
        </bindingFiles>
        <wsdlUrls>
            <wsdlUrl>http://www5v80.elsyarres.net/service.asmx?wsdl</wsdlUrl>
        </wsdlUrls>
        <vmArgs>
            <vmArg>-Djavax.xml.accessExternalSchema=all</vmArg>
        </vmArgs>
    </configuration>
</plugin>

Solution 2

If the autoNameResolution fix

 <args>
     <arg>-XautoNameResolution</arg>
 </args>

doesn't work, try:

 <args>
     <arg>-B-XautoNameResolution</arg>
 </args>

Solution 3

Removing <generatePackage></generatePackage> tag solves the problem.

However, the consequence of this removal is that your packages will be created from the xml namespace. For example, the namespace example.com/xyz will result to the package com.example.xyz

Solution 4

Removing generatePackage as hamid-mohayeji mentions fixes a lot of cases (at least cases where your xsds are sane). The setting tries to put all entities into the same namespace and that's bound to go wrong in non-simple cases. However omitting the package leaves you with packages created from the namespace. For example http://www.co.com/srvc/api/common would become package com.co.srvc.api.common.

This can be remedied by adding a simple binding file. Configure <bindingDirectory>src/main/resources/bindings</bindingDirectory> in the pom and add a binding file something.xjb to the binding directory. Here you need to refer to individual relatively to this file.

This file sets packages for each xsd-file individually:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0">

    <jaxb:bindings schemaLocation="../schemas/common.xsd">
        <jaxb:schemaBindings>
            <jaxb:package name="com.mycomp.myapp.co.common" />
        </jaxb:schemaBindings>
    </jaxb:bindings>

    ... more bindings

</jaxb:bindings>

Solution 5

I had the same problem for xsd to jaxb and using jaxb2-maven-plugin from org.codehaus.mojo. There was a packageName under configuration creates all the generated files under the same package caused the issue

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>1.5</version>
    <executions>
        <execution>
            <goals>
                <goal>xjc</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <outputDirectory>target/generated-sources/jaxb</outputDirectory>
        <schemaDirectory>src/main/xsd</schemaDirectory>
        <schemaFiles>test.xsd</schemaFiles>
        <!-- <packageName>com.example.myschema</packageName> -->
    </configuration>
</plugin>
Share:
54,214

Related videos on Youtube

Daniel Newtown
Author by

Daniel Newtown

Highly motivated to improve programming skills.

Updated on February 04, 2021

Comments

  • Daniel Newtown
    Daniel Newtown over 3 years

    I am trying to use Maven to generate JAXB files to be used by Spring framework, but Maven displays following errors:

    I understand that it is unable to generate files with the names, but I am not sure how to resolve the issue. So far, I visited following links. 1, 2, 3

    org.xml.sax.SAXParseException; systemId: http://www5v80.elsyarres.net/service.asmx?wsdl; lineNumber: 5; columnNumber: 39; A class/interface with the same name "hello.wsdl.SearchFlights" is already in use. Use a class customization to resolve this conflict.
    ....
    org.xml.sax.SAXParseException; systemId: http://www5v80.elsyarres.net/service.asmx?wsdl; lineNumber: 12; columnNumber: 43; (Relevant to above error) another "SearchFlights" is generated from here.
    ....
    org.xml.sax.SAXParseException; systemId: http://www5v80.elsyarres.net/service.asmx?wsdl; lineNumber: 371; columnNumber: 42; A class/interface with the same name "hello.wsdl.GetFlightDetails" is already in use. Use a class customization to resolve this conflict.
    ....
    

    Maven plugin

        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <warSourceDirectory>WebContent</warSourceDirectory>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.12.3</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <schemaLanguage>WSDL</schemaLanguage>
                <generatePackage>hello.wsdl</generatePackage>
                <schemas>
                    <schema>
                        <url>http://www5v80.elsyarres.net/service.asmx?wsdl</url>
                    </schema>
                </schemas>
            </configuration>
        </plugin>
    

    I added following package-info.java file to the hello.wsdl package but it did not help.

    @XmlSchema( 
        namespace = "ElsyArres.API",
        elementFormDefault = XmlNsForm.QUALIFIED) 
    package hello.wsdl;
    
    import javax.xml.bind.annotation.XmlNsForm;
    import javax.xml.bind.annotation.XmlSchema;
    
    • Khuzi
      Khuzi about 6 years
      were you able to fix this issue?? If yes, how? I am also facing similar issue and I dont want to go ahead with <arg>-XautoNameResolution</arg> option. I am interested for binding approach.
  • Francesco Carlucci
    Francesco Carlucci over 6 years
    thanks, this works also with wsimport utility from jdk
  • Khuzi
    Khuzi about 6 years
    I am interested for binding approach. Were you able to get working with org.jvnet.jaxb2.maven2:maven-jaxb2-plugin ??
  • andrew
    andrew over 5 years
    This does seem like the easiest solution. Seems to work for me. I wonder what the drawbacks are.
  • Admin
    Admin over 4 years
    <arg>-XautoNameResolution</arg> works but now I am getting error Two declarations cause a collision in the ObjectFactory class. Any suggestions??
  • Delli Kilari
    Delli Kilari about 4 years
    Exactly, after spending good amount of time able to generate source, would like to know the drawbacks of it.
  • sen
    sen over 2 years
    I used the <arg>-XautoNameResolution</arg> solution, and fixed the problem perfectly. Thanks for the solution! spent a day on it.