I am struggling with some conflicts while generating code from a bunch of WSDL files using wsdl2java via cxf-codegen-plugin with Maven. WSDLs declare different APIs of the same system, and the generated code has some overlap (especially with model classes). The external system and WSDL come from a third party and therefore are not controlled by us.
The first problem I encountered was a name conflict in one of the resulting ObjectFactory classes ObjectFactory by one of the WSDLs. It defines a complexType named Foo that contains an element named Status , and also defines an element named FooStatus . When the code is generated, the JAXB throws a match because the ObjectFactory will have two factory methods called createFooStatus(...) , and I get an exception at runtime. I tried to provide the -autoNameResolution option in wsdl2java to no avail. I looked at “Two declarations cause a collision in the ObjectFactory class” and “Applying an external JAXB binding file to schema elements imported from WSDL” , and based on those that I wrote an external binding file that renames one of the factory methods. I use SCD instead of XPath in the binding file, as shown in the last link, because I had the same XPath problem as the author. This works, but only if I process the WSDL files individually and apply the bind file only to the WSDL, which causes a conflict. Maven configuration is as follows:
<plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>3.0.0-milestone1</version> <executions> <execution> <id>generate-proxies</id> <phase>generate-sources</phase> <configuration> <wsdlOptions> <wsdlOption> <wsdl>${basedir}/First.wsdl</wsdl> <bindingFiles> <bindingFile>${basedir}/bindings.xml</bindingFile> </bindingFiles> </wsdlOption> <wsdlOption> <wsdl>${basedir}/Second.wsdl</wsdl> </wsdlOption> <wsdlOption> <wsdl>${basedir}/Third.wsdl</wsdl> </wsdlOption> ... More wsdlOption declarations ... </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin>
Now, if I do this, I have a different problem because the generated code from different WSDL files uses the same package structure. In practice, this means that the ObjectFactory classes ObjectFactory overridden during the processing of subsequent WSDL files, which means that after the plug-in is executed, only the one created from the last WSDL will exist. I know that I can change the structure of the target package, but the code created from different WSDLs has many overlaps, and it would be foolish to duplicate it. I also tried using the -keep wsdl2java option, but that doesn't seem to do anything (or at least the ObjectFactory classes ObjectFactory still overridden). I understand that the solution to this is to handle all WSDLs at a time with a Maven configuration like this (only the configuration section is shown, everything else remains the same):
<configuration> <defaultOptions> <bindingFiles> <bindingFile>${basedir}/bindings.xml</bindingFile> </bindingFiles> </defaultOptions> <wsdlRoot>${basedir}</wsdlRoot> <includes> <include>*.wsdl</include> </includes> </configuration>
However, this leads to com.sun.istack.SAXParseException2 , saying that my SCD expression does not match any schema component (since the schema component exists in only one of the WSDLs).
I can get the result that I want if I modify the WSDL file itself and use the latest Maven configuration without a binding file. By doing this, the resulting ObjectFactory is a merge of those that will be created when processing WSDL separately with the first Maven configuration. However, I would prefer not to do this, but instead I would like to manage this using an external binding file. How do I solve this? Can I write / apply a binding file so that an exception does not occur if the corresponding circuit component is not found? Or can I handle WSDL separately and not overwrite ObjectFactory classes? Or do I just need to suck it and generate code from different WSDLs into different packages or edit the WSDL files themselves? Just in case, it matters, my current binding file looks like this (WSDLs are inside my project in the same directory with the required file):
<bindings scd="x-schema::tns" xmlns:tns="NamespaceOfFoo" xmlns="http://java.sun.com/xml/ns/jaxb" version="2.1"> <bindings scd="tns:FooStatus"> <factoryMethod name="FooStatusType"/> </bindings> </bindings>