Search code examples
javajaxbjax-wswsdl2java

Element has the same name with different types in WSDL


I was given a WSDL and schema files. I'm using these files to create the stubs in Java. But I'm getting an error when generating the error (below). I know what the problem is I just don't know how to fix it. I understand what the problem is that at times the PayLoadLength is at times string or integer

<xs:element name="PayloadLength" type="xs:string" minOccurs="0"/>

or

<xs:element name="PayloadLength" maxOccurs="1" minOccurs="0" type="xs:int"/>

schema file (portion of the file where you can see PayloadLength that is either an int or string:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>-->
<xs:schema version="1.0" targetNamespace="xxxxxx" xmlns:tns="xxxxxxxxxx" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="ABCBatchResultsAckSubmission" type="tns:ABCBatchResultsAckSubmission"/>

  <xs:element name="ABCBatchResultsAckSubmissionResponse" type="tns:ABCBatchResultsAckSubmissionResponse"/>

  <xs:element name="ABCBatchResultsRetrievalRequest" type="tns:ABCBatchResultsRetrievalRequest"/>

  <xs:element name="ABCBatchResultsRetrievalRequestResponse" type="tns:ABCBatchResultsRetrievalRequestResponse"/>

  <xs:element name="ABCBatchSubmission" type="tns:ABCBatchSubmission"/>

  <xs:element name="ABCBatchSubmissionAckRetrievalRequest" type="tns:ABCBatchSubmissionAckRetrievalRequest"/>

  <xs:element name="ABCBatchSubmissionAckRetrievalRequestResponse" type="tns:ABCBatchSubmissionAckRetrievalRequestResponse"/>

  <xs:element name="ABCBatchSubmissionResponse" type="tns:ABCBatchSubmissionResponse"/>

  <xs:complexType name="ABCBatchSubmissionAckRetrievalRequest">
    <xs:sequence>

        <xs:element name="PayloadLength" type="xs:string" minOccurs="0"/>

    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ABCBatchSubmissionAckRetrievalRequestResponse">
    <xs:sequence>

    <xs:element name="PayloadLength" maxOccurs="1" minOccurs="0" type="xs:int"/>

    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ABCBatchSubmission">
    <xs:sequence>

      <xs:element name="PayloadLength" type="xs:string" minOccurs="0"/>

    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ABCBatchSubmissionResponse">
    <xs:sequence>

        <xs:element name="PayloadLength" maxOccurs="1" minOccurs="0" type="xs:int"/>


    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ABCBatchResultsRetrievalRequest">
    <xs:sequence>

      <xs:element name="PayloadLength" type="xs:string" minOccurs="0"/>

    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ABCBatchResultsRetrievalRequestResponse">
    <xs:sequence>

        <xs:element name="PayloadLength" maxOccurs="1" minOccurs="0" type="xs:int"/>

    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ABCBatchResultsAckSubmission">
    <xs:sequence>

      <xs:element name="PayloadLength" type="xs:string" minOccurs="0"/>

    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ABCBatchResultsAckSubmissionResponse">
    <xs:sequence>

        <xs:element name="PayloadLength" maxOccurs="1" minOccurs="0" type="xs:int"/>

    </xs:sequence>
  </xs:complexType>
</xs:schema>

So I know I need to create an JAXB Binding file to fix issue. I'm pretty sure this is wrong (below). But I think I need to target the PayLoadLength and change its name to something else. Is that right?

pom.xml

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-codegen-plugin</artifactId>
                <version>3.2.1</version>
                <executions>
                    <execution>
                        <id>generate-sources</id>
                        <phase>generate-sources</phase>
                        <configuration>
                            <sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
                            <wsdlOptions>
                                <wsdlOption>
                                    <wsdl>${basedir}/src/main/resources/wsdl/CORETransactionService.wsdl</wsdl>
                                    <wsdlLocation>classpath:wsdl/CORETransactionService.wsdl</wsdlLocation>
                                </wsdlOption>
                            </wsdlOptions>
                        </configuration>
                        <goals>
                            <goal>wsdl2java</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Error:

Execution generate-sources of goal org.apache.cxf:cxf-codegen-plugin:3.2.1:wsdl2java failed: Element PayloadLength has the same name with different types[{http://www.w3.org/2001/XMLSchema}string -- {http://
 www.w3.org/2001/XMLSchema}int]. This will cause a collision in wrapper style as per the spec. (org.apache.cxf:cxf-codegen-plugin:3.2.1:wsdl2java:generate-sources:generate-sources) 
 org.apache.maven.plugin.PluginExecutionException: Execution generate-sources of goal org.apache.cxf:cxf-codegen-plugin:3.2.1:wsdl2java failed: Element PayloadLength has the same name with different types[{http://
 www.w3.org/2001/XMLSchema}string -- {http://www.w3.org/2001/XMLSchema}int]. This will cause a collision in wrapper style as per the spec. at 
 org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:145) at org.eclipse.m2e.core.internal.embedder.MavenImpl.execute(MavenImpl.java:331) at 
 org.eclipse.m2e.core.internal.embedder.MavenImpl$11.call(MavenImpl.java:1362) at org.eclipse.m2e.core.internal.embedder.MavenImpl$11.call(MavenImpl.java:1) at 
 org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:177) at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:
 112) at org.eclipse.m2e.core.internal.embedder.MavenImpl.execute(MavenImpl.java:1360) at org.eclipse.m2e.core.project.configurator.MojoExecutionBuildParticipant.build(MojoExecutionBuildParticipant.java:52) at 
 org.eclipse.m2e.core.internal.builder.MavenBuilderImpl.build(MavenBuilderImpl.java:137) at org.eclipse.m2e.core.internal.builder.MavenBuilder$1.method(MavenBuilder.java:172) at 
 org.eclipse.m2e.core.internal.builder.MavenBuilder$1.method(MavenBuilder.java:1) at org.eclipse.m2e.core.internal.builder.MavenBuilder$BuildMethod$1$1.call(MavenBuilder.java:115) at 
 org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:177) at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:
 112) at org.eclipse.m2e.core.internal.builder.MavenBuilder$BuildMethod$1.call(MavenBuilder.java:105) at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:177) 
 at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:151) at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:99) 
 at org.eclipse.m2e.core.internal.builder.MavenBuilder$BuildMethod.execute(MavenBuilder.java:86) at org.eclipse.m2e.core.internal.builder.MavenBuilder.build(MavenBuilder.java:200) at 
 org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:735) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:
 206) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:246) at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:301) at 
 org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:304) at 
 org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:360) at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:383) at 
 org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:142) at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:232) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56) 
 Caused by: org.apache.cxf.tools.common.ToolException: Element PayloadLength has the same name with different types[{http://www.w3.org/2001/XMLSchema}string -- {http://www.w3.org/2001/XMLSchema}int]. This 
 will cause a collision in wrapper style as per the spec. at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.validate(WSDLToJavaContainer.java:735) at 
 org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.processWsdl(WSDLToJavaContainer.java:276) at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:164) at 
 org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:412) at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:105) at 
 org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:113) at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:86) at 
 org.apache.cxf.maven_plugin.wsdl2java.WSDL2JavaMojo.generate(WSDL2JavaMojo.java:414) at org.apache.cxf.maven_plugin.AbstractCodegenMoho.execute(AbstractCodegenMoho.java:279) at 
 org.apache.cxf.maven_plugin.wsdl2java.WSDL2JavaMojo.execute(WSDL2JavaMojo.java:511) at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134) ... 31 more

Solution

  • After quite an extensive analysis, the problem appeared to be in the so-called "wrapper style". To quote WSDL To Java:

    Note: The meaning of "wrapper-style" and "non-wrapper style" as defined in the JAX-WS 2.1 specification can be counterintuitive. Wrapper-style indicates that each data element within the request message gets its own Java parameter, while non-wrapper style means that a single Java object containing all the data elements serves as the lone parameter to the web service method call.

    So basically the problem is that if you have some sub-elements in the request and the response types which have the same name, they will essentially map to one parameter. And if they have different types, this causes a collision and CXF rejects them.

    One way to resolve this is to disable wrapper style. You can do this with a binding.xml file like:

    <jaxws:bindings node="wsdl:definitions" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
        <jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
    </jaxws:bindings>
    

    Include it in the configuration of the cxf-codegen-plugin:

            <plugin>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-codegen-plugin</artifactId>
                <version>3.2.1</version>
                <executions>
                    <execution>
                        <id>generate-sources</id>
                        <phase>generate-sources</phase>
                        <configuration>
                            <wsdlOptions>
                                <wsdlOption>
                                    <wsdl>${basedir}/src/main/resources/wsdl/My.wsdl</wsdl>
                                    <wsdlLocation>classpath:wsdl/My.wsdl</wsdlLocation>
                                    <bindingFiles>
                                        <bindingFile>${basedir}/src/main/resources/bindings.xml</bindingFile>
                                    </bindingFiles>
                                </wsdlOption>
                            </wsdlOptions>
                        </configuration>
                        <goals>
                            <goal>wsdl2java</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
    

    There is also probably another way, at least the error message, at least the error message suggests that it should be possible to "use a JAXWS/JAXB binding customization to rename the parameter". Unfortunately I could not figure out the right syntax of bindings for this.