Question

I'm working on a JAX-WS service with Apache CXF which takes its type definitions from two sources. An XSD schema file defines various types in a .../types/ namespace and there are the matching java classes with JAXB annotations. The endpoint is defined in a Java inteface with the @WebService related annotations inside the .../service/ namespace. The WSDL is generated by Apache CXF and it uses the type definitions from the XSD schema file together with generated type definitions for the request/response messages and parameters, taken from the @WebService endpoint.

I've run into the following validator error about one of the Apache CXF generated types inside the .../service/ namespace.

Caused by: org.xml.sax.SAXParseException; lineNumber: 5; columnNumber: 10; cvc-elt.1: Cannot find the declaration of element 'ser:subscriberId'.

The endpoint is defined like this in the .../service/ namespace:

@WebService(name="gatewayService",
    targetNamespace="http://www.mydomain.com/gateway/schema/service/")
public interface GatewayEndpoint {
    // ...
    @WebMethod(operationName="addService")
    @XmlElement(required=true) public Response addService(
            @XmlElement(required=true) @WebParam(name="subscriberId") long subscriberId,
            @XmlElement(required=true) @WebParam(name="service") Service service)
            throws GatewayException;
    // ...
}

The JAX-WS endpoint is defined in a spring configuration file as such:

<!-- Apache CXF endpoint -->
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<jaxws:endpoint id="gatewayndpoint" implementor="#gatewayEndpointImpl" address="/gateway">
     <jaxws:schemaLocations>
        <jaxws:schemaLocation>classpath:/schemas/gateway_schema.xsd</jaxws:schemaLocation>
    </jaxws:schemaLocations>
    <jaxws:properties>
        <entry key="schema-validation-enabled" value="true" />
    </jaxws:properties>
</jaxws:endpoint>

The gateway_schema.xsd contains various complexType definitions among them the Service definition in the .../types/ namespace:

<xs:complexType name="Service">
<xs:sequence>
  <xs:element name="name">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:maxLength value="10"/>
        </xs:restriction>
    </xs:simpleType>
  </xs:element>
  <xs:element name="deviceLimit" type="xs:int"/>
  <xs:element maxOccurs="unbounded" minOccurs="0" name="subscription" nillable="true" type="gateway:Subscription"/>
  <xs:element maxOccurs="unbounded" minOccurs="0" name="package" nillable="true" type="gateway:Package"/>
</xs:sequence>
</xs:complexType>

And the matching JAXB annotated class is:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Service")
public class Service {

    @XmlElement(required=true)
    private String name;
    private int deviceLimit;
    @XmlElement(name="subscription", nillable=true)
    private List<Subscription> subscriptions;
    @XmlElement(name="package", nillable=true)
    private List<Package> packages;

    //.. getters and setters
}

Everything is packaged in a war file and after deployment the generated WSDL looks like this:

<?xml version="1.0" ?>
<wsdl:definitions
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://www.mydomain.com/gateway/schema/service/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:ns2="http://schemas.xmlsoap.org/soap/http"
    xmlns:ns1="http://www.mydomain.com/gateway/schema/services/"
    name="GatewayService"
    targetNamespace="http://www.mydomain.com/gateway/schema/service/">
    <wsdl:types>
        <xs:schema
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:gateway="http://www.mydomain.com/gateway/schema/types/"
            elementFormDefault="qualified"
            targetNamespace="http://www.mydomain.com/gateway/schema/types/"
            version="1.0">
            <!--
                Various type definitions available in the gateway_schema.xsd
                Among them the typ:Service definition
            -->
        </xs:schema>
        <xsd:schema
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:tns="http://www.mydomain.com/gateway/schema/services/"
            xmlns:ns0="http://www.mydomain.com/gateway/schema/types/"
            attributeFormDefault="unqualified"
            elementFormDefault="qualified"
            targetNamespace="http://www.mydomain.com/gateway/schema/services/">

            <xsd:import namespace="http://www.mydomain.com/gateway/schema/types/"></xsd:import>

            <!--
                Definitions generated by Apache CXF
            -->
            <xsd:element name="addService" type="tns:addService"></xsd:element>
            <xsd:complexType name="addService">
                <xsd:sequence>
                    <xsd:element name="subscriberId" type="xsd:long"></xsd:element>
                    <xsd:element name="service" type="ns0:Service"></xsd:element>\
                </xsd:sequence>
            </xsd:complexType>
            <!-- .... -->
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="addService">
        <wsdl:part element="tns:addService" name="parameters"></wsdl:part>
    </wsdl:message>
    <!... rest of messages, portTypes, bindings and wsdl:service -->
</wsdl:definitions>

A SoapUI generated request for this service is this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://www.mydomain.com/gateway/schema/service/" xmlns:typ="http://www.mydomain.com/gateway/schema/types/">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:addService>
         <ser:subscriberId>100</ser:subscriberId>
         <ser:service>
            <typ:name>12345678</typ:name>
            <typ:deviceLimit>1</typ:deviceLimit>
            <!--Zero or more repetitions:-->
            <typ:subscription name="a"/>
            <!--Zero or more repetitions:-->
            <typ:package name="b"/>
         </ser:service>
      </ser:addService>
   </soapenv:Body>
</soapenv:Envelope>

An the validator responds with this validation error, about the subscriberId element:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <soap:Fault>
         <faultcode>soap:Client</faultcode>
         <faultstring>Unmarshalling Error: cvc-elt.1: Cannot find the declaration of element 'ser:subscriberId'.</faultstring>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

It's strange to me that the validator fails for one of the generated types corresponding to a method call parameter which is a simple long. Anyone have a hint what might be the problem?

Apache CXF version is 2.7.10 and I'm using Java 1.7, so I guess it's using whatever JAXB implementation is in there.

Was it helpful?

Solution

You have a namespace problem... In the wsdl, you have the namespace of "http://www.mydomain.com/gateway/schema/services/" for the addService/subscriberId elements, but you are sending "http://www.mydomain.com/gateway/schema/service/". Note the lack of "s" on the end.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top