Search code examples
javamavensoapxsdwsdl

Missing classes in @XmlSeeAlso annotation of generated Java class


I'm generating Java classes (and then packaging a jar based on them) from wsdl/xsd files, using Maven's cxf-codegen-plugin. I chose this plugin over other options because it allows me to "dynamically" reference all wsdl and xsd files in a folder instead of "statically" writing them down one by one in <wsdl/> tags.

The FurtherExtensionOfBaseObj Java class (defined in the internet.xsd file) is implemented by both MyBarRequest (from bar.wsdl) and MyZedRequest (from zed.wsdl) but in its @XmlSeeAlso annotation only MyBarRequest.class is referenced.

It's as if the plugin only considered what he finds in the first wsdl processed (alphabetically ordered) and nothing else. How I can I get the plugin (or any other plugin, although I like this one) to reference all extending classes in the @XmlSeeAlso annotation?

You can pull a working project reproducing exactly this issue at https://gitlab.com/t.meledina/xmlseealso-issue-poc

EDIT: the issue is now solved, the repository is now a working example of Tomas' solution below.

Alternatively, the following list of files can be used in order to reproduce the issue, the common.xsd should be irrelevant but it's needed in order to compile.

common.xsd file

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://www.somehost.com/common/beans" xmlns:beans="http://www.somehost.com/common/beans" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:complexType name="SomeCommonObj">
        <xsd:sequence>
            <xsd:element name="woop" type="xsd:int"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="ExtensionOfSomeCommonObj">
        <xsd:complexContent>
            <xsd:extension base="beans:SomeCommonObj">
                <xsd:sequence>
                    <xsd:element name="moreWoop" type="xsd:string"/>
                </xsd:sequence>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>
    <xsd:complexType name="BaseRequest">
        <xsd:sequence>
            <xsd:element name="floop" type="xsd:int"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="BaseResponse">
        <xsd:sequence>
            <xsd:element name="scoop" type="xsd:int"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="AnotherCommonObj">
        <xsd:annotation>
            <xsd:documentation>whatever</xsd:documentation>
        </xsd:annotation>
        <xsd:sequence/>
    </xsd:complexType>
    <xsd:complexType name="ExtensionOfAnotherCommonObj">
        <xsd:annotation>
            <xsd:documentation>son of whatever</xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:extension base="beans:AnotherCommonObj">
                <xsd:sequence>
                    <xsd:element minOccurs="1" name="goop" type="xsd:int"/>
                </xsd:sequence>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>
    <xsd:complexType name="BarObj">
        <xsd:sequence>
            <xsd:element name="noop" type="xsd:string"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

internet.xsd file

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://www.somehost.com/internet/beans" xmlns:tns="http://www.somehost.com/internet/beans" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:import namespace="http://www.somehost.com/common/beans" schemaLocation="common.xsd"/>
    <xsd:complexType name="BaseObj">
        <xsd:sequence>
            <xsd:element name="zeep" type="xsd:int"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="ExtensionOfBaseObj">
        <xsd:complexContent>
            <xsd:extension base="tns:BaseObj">
                <xsd:sequence>
                    <xsd:element name="moreZeep" type="xsd:int"/>
                </xsd:sequence>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>
    <xsd:complexType name="SomeOtherObj">
        <xsd:sequence>
            <xsd:element name="neep" type="xsd:string"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="YetSomeOtherObj">
        <xsd:sequence>
            <xsd:element name="geep" type="xsd:dateTime"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="FurtherExtensionOfBaseObj">
        <xsd:complexContent>
            <xsd:extension base="tns:ExtensionOfBaseObj">
                <xsd:sequence>
                    <xsd:element name="evenMoreZeep" type="xsd:string"/>
                </xsd:sequence>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>
</xsd:schema>

bar.wsdl file

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="bar" targetNamespace="http://www.somehost.com/internet/bar/" xmlns:beans="http://www.somehost.com/internet/bar/beans/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://www.somehost.com/internet/bar/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <wsdl:types>
        <xsd:schema jaxb:version="2.0" targetNamespace="http://www.somehost.com/internet/bar/beans/" xmlns:common="http://www.somehost.com/common/beans" xmlns:internet="http://www.somehost.com/internet/beans" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
            <xsd:import namespace="http://www.somehost.com/common/beans" schemaLocation="common.xsd"/>
            <xsd:import namespace="http://www.somehost.com/internet/beans" schemaLocation="internet.xsd"/>
            <xsd:annotation>
                <xsd:appinfo>
                    <jaxb:globalBindings>
                        <jaxb:javaType name="java.util.Calendar" parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" printMethod="javax.xml.bind.DatatypeConverter.printDateTime" xmlType="xsd:dateTime"/>
                    </jaxb:globalBindings>
                </xsd:appinfo>
            </xsd:annotation>
            <xsd:complexType name="myBarRequest">
                <xsd:complexContent>
                    <xsd:extension base="internet:FurtherExtensionOfBaseObj">
                        <xsd:sequence>
                            <xsd:element minOccurs="0" name="barObjAttuale" type="common:BarObj"/>
                            <xsd:element name="barObjNuovo" type="common:BarObj"/>
                        </xsd:sequence>
                    </xsd:extension>
                </xsd:complexContent>
            </xsd:complexType>
            <xsd:element name="myBarRequestElement" type="beans:myBarRequest"/>
            <xsd:complexType name="myBarResponse">
                <xsd:complexContent>
                    <xsd:extension base="common:BaseResponse">
                        <xsd:sequence minOccurs="0">
                            <xsd:element name="barObj" type="common:BarObj"/>
                        </xsd:sequence>
                    </xsd:extension>
                </xsd:complexContent>
            </xsd:complexType>
            <xsd:element name="myBarResponseElement" type="beans:myBarResponse"/>
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="myBarRequest">
        <wsdl:part element="beans:myBarRequestElement" name="parameters"/>
    </wsdl:message>
    <wsdl:message name="myBarResponse">
        <wsdl:part element="beans:myBarResponseElement" name="parameters"/>
    </wsdl:message>
    <wsdl:portType name="barPortType">
        <wsdl:operation name="myBar">
            <wsdl:input message="tns:myBarRequest"/>
            <wsdl:output message="tns:myBarResponse"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="barBinding" type="tns:barPortType">
        <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="myBar">
            <wsdl:input>
                <soap12:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap12:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="barService">
        <wsdl:port binding="tns:barBinding" name="barPort">
            <soap12:address location="http://localhost:9080/internet/barService"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

zed.wsdl file

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="zedService" targetNamespace="http://www.somehost.com/internet/zed/" xmlns:beans="http://www.somehost.com/internet/zed/beans/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://www.somehost.com/internet/zed/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <wsdl:types>
        <xsd:schema jaxb:version="2.0" targetNamespace="http://www.somehost.com/internet/zed/beans/" xmlns:common="http://www.somehost.com/common/beans" xmlns:internet="http://www.somehost.com/internet/beans" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
            <xsd:import namespace="http://www.somehost.com/common/beans" schemaLocation="common.xsd"/>
            <xsd:import namespace="http://www.somehost.com/internet/beans" schemaLocation="internet.xsd"/>
            <xsd:annotation>
                <xsd:appinfo>
                    <jaxb:globalBindings>
                        <jaxb:javaType name="java.util.Calendar" parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" printMethod="javax.xml.bind.DatatypeConverter.printDateTime" xmlType="xsd:dateTime"/>
                    </jaxb:globalBindings>
                </xsd:appinfo>
            </xsd:annotation>
            <xsd:complexType name="myZedRequest">
                <xsd:complexContent>
                    <xsd:extension base="internet:FurtherExtensionOfBaseObj">
                        <xsd:sequence>
                            <xsd:element minOccurs="1" name="blaap" type="xsd:long"/>
                        </xsd:sequence>
                    </xsd:extension>
                </xsd:complexContent>
            </xsd:complexType>
            <xsd:element name="myZedRequestElement" type="beans:myZedRequest"/>
            <xsd:complexType name="myZedResponse">
                <xsd:complexContent>
                    <xsd:extension base="common:BaseResponse">
                        <xsd:sequence minOccurs="0"/>
                    </xsd:extension>
                </xsd:complexContent>
            </xsd:complexType>
            <xsd:element name="myZedResponseElement" type="beans:myZedResponse"/>
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="myZedRequest">
        <wsdl:part element="beans:myZedRequestElement" name="parameters"/>
    </wsdl:message>
    <wsdl:message name="myZedResponse">
        <wsdl:part element="beans:myZedResponseElement" name="parameters"/>
    </wsdl:message>
    <wsdl:portType name="zedPortType">
        <wsdl:operation name="myZed">
            <wsdl:input message="tns:myZedRequest"/>
            <wsdl:output message="tns:myZedResponse"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="zedBinding" type="tns:zedPortType">
        <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="myZed">
            <wsdl:input>
                <soap12:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap12:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="zedService">
        <wsdl:port binding="tns:zedBinding" name="zedPort">
            <soap12:address location="http://localhost:9080/internet/zedService"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

pom.xml file

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mytest.mobile</groupId>
    <artifactId>mytest-jax-ws</artifactId>
    <version>20190707-1950</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-codegen-plugin</artifactId>
                <version>3.1.17</version>
                <executions>
                    <execution>
                        <id>generate-sources</id>
                        <phase>generate-sources</phase>
                        <configuration>
                            <wsdlRoot>src/main/resources/wsdl</wsdlRoot>
                            <includes>
                                <include>*.wsdl</include>
                            </includes>
                        </configuration>
                        <goals>
                            <goal>wsdl2java</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <version>2.4.1</version>
                <executions>
                    <execution>
                        <id>auto-clean</id>
                        <phase>initialize</phase>
                        <goals>
                            <goal>clean</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-codegen-plugin</artifactId>
            <version>3.2.7</version>
        </dependency>
    </dependencies>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>
</project>

Thank you in advance for any help.


Solution

  • I have explicitly overwritten generated classes from WSDL generation by XSD generation with proper annotations. Please add whole text to pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.test</groupId>
        <artifactId>my-jax-ws</artifactId>
        <version>20190707-1950</version>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.cxf</groupId>
                    <artifactId>cxf-codegen-plugin</artifactId>
                    <version>3.1.17</version>
                    <executions>
                        <execution>
                            <id>generate-sources</id>
                            <phase>generate-sources</phase>
                            <configuration>
                                <wsdlRoot>src/main/resources/wsdl</wsdlRoot>
                                <includes>
                                    <include>*.wsdl</include>
                                </includes>
                             </configuration>
                            <goals>
                                <goal>wsdl2java</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.cxf</groupId>
                    <artifactId>cxf-xjc-plugin</artifactId>
                    <version>3.3.1</version>
                    <executions>
                        <execution>
                            <id>generate-sources</id>
                            <phase>generate-sources</phase>
                            <configuration>
                                <sourceRoot>${basedir}/target/generated-sources/cxf</sourceRoot>
                                <xsdOptions>
                                    <xsdOption>
                                        <xsd>src/main/resources/wsdl/internet.xsd</xsd>
                                        <bindingFiles>
                                            <bindingFile>src/main/resources/bindings.xjb</bindingFile>
                                        </bindingFiles>
                                        <extension>true</extension>
                                        <extensionArgs>
                                            <extensionArg>-Xannotate</extensionArg>
                                        </extensionArgs>
                                    </xsdOption>
                                </xsdOptions>
                            </configuration>
                            <goals>
                                <goal>xsdtojava</goal>
                            </goals>
                        </execution>
                    </executions>
                    <dependencies>
                        <dependency>
                            <groupId>org.jvnet.jaxb2_commons</groupId>
                            <artifactId>jaxb2-basics</artifactId>
                            <version>1.11.1</version>
                        </dependency>
                        <dependency>
                            <groupId>org.jvnet.jaxb2_commons</groupId>
                            <artifactId>jaxb2-basics-annotate</artifactId>
                            <version>1.0.2</version>
                        </dependency>
                    </dependencies>
                </plugin>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>2.4.1</version>
                    <executions>
                        <execution>
                            <id>auto-clean</id>
                            <phase>initialize</phase>
                            <goals>
                                <goal>clean</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
        <dependencies>
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-codegen-plugin</artifactId>
                <version>3.2.7</version>
            </dependency>
        </dependencies>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.7</maven.compiler.source>
            <maven.compiler.target>1.7</maven.compiler.target>
        </properties>
    </project>
    

    And create bindings.xjb file in folder: xmlseealso-issue-poc\src\main\resources with following code:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:annox="http://annox.dev.java.net" 
                   xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
                   version="2.1">
    
            <jaxb:bindings schemaLocation="wsdl\internet.xsd" node="/xsd:schema">
            <jaxb:bindings node="xsd:complexType[@name='FurtherExtensionOfBaseObj']">
                    <annox:annotate target="class">
                        @javax.xml.bind.annotation.XmlSeeAlso({com.somehost.internet.zed.beans.MyZedRequest.class, com.somehost.internet.bar.beans.MyBarRequest.class})
                    </annox:annotate>
            </jaxb:bindings>
        </jaxb:bindings>
    
    
    </jaxb:bindings>
    

    I hope it helps.