title: JAX-WS web-service defined by WSDL with abstract global elements
body: <p>Here is a WSDL containing abstract global element named paramName:</p>
  
  <pre><code>   &lt;wsdl:definitions name="AdapterSessionManagerService" targetNamespace="http://companyname.org/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://companyname.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
     &lt;wsdl:types&gt;
        &lt;xs:schema elementFormDefault="unqualified" targetNamespace="http://companyname.org/" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
      &lt;import namespace="http://companyname.org/adapter1/" schemaLocation="http://localhost:8081/adapters/AdapterSessionManager?xsd=adapter1/ElementName.xsd"/&gt;
      &lt;import namespace="http://companyname.org/adapter2/" schemaLocation="http://localhost:8081/adapters/AdapterSessionManager?xsd=adapter2/ElementName.xsd"/&gt;
  
           &lt;xs:element name="initAdapterSession" type="tns:initAdapterSession"/&gt;
           &lt;xs:element name="initAdapterSessionResponse" type="tns:initAdapterSessionResponse"/&gt;
           &lt;xs:complexType name="initAdapterSession"&gt;
              &lt;xs:sequence&gt;
                 &lt;xs:element name="adapterId" type="xs:long"/&gt;
                 &lt;xs:element name="callbackURL" type="xs:anyURI"/&gt;
                 &lt;xs:element name="adapterInputData" type="tns:AdapterInputDataType"/&gt;
              &lt;/xs:sequence&gt;
           &lt;/xs:complexType&gt;
           &lt;xs:complexType name="initAdapterSessionResponse"&gt;
              &lt;xs:sequence&gt;
                 &lt;xs:element minOccurs="0" name="return" type="xs:long"/&gt;
              &lt;/xs:sequence&gt;
           &lt;/xs:complexType&gt;
           &lt;xs:complexType name="AdapterInputDataType"&gt;
              &lt;xs:sequence&gt;
                 &lt;xs:element maxOccurs="unbounded" minOccurs="0" name="atomicParam" type="tns:AtomicParamType"/&gt;
              &lt;/xs:sequence&gt;
           &lt;/xs:complexType&gt;
           &lt;xs:complexType name="AtomicParamType"&gt;
              &lt;xs:sequence&gt;
                 &lt;xs:element maxOccurs="1" minOccurs="1" ref="tns:paramName"/&gt;
                 &lt;xs:element maxOccurs="1" minOccurs="1" name="paramValue" type="tns:AtomicParamValueType"/&gt;
              &lt;/xs:sequence&gt;
           &lt;/xs:complexType&gt;
           &lt;xs:simpleType name="AtomicParamValueType"&gt;
              &lt;xs:union memberTypes="xs:string xs:long xs:decimal xs:dateTime xs:boolean"/&gt;
           &lt;/xs:simpleType&gt;
           &lt;xs:element abstract="true" name="paramName" type="xs:string"/&gt;
        &lt;/xs:schema&gt;
     &lt;/wsdl:types&gt;
     &lt;wsdl:message name="initAdapterSessionResponse"&gt;
        &lt;wsdl:part element="tns:initAdapterSessionResponse" name="parameters"/&gt;
     &lt;/wsdl:message&gt;
     &lt;wsdl:message name="initAdapterSession"&gt;
        &lt;wsdl:part element="tns:initAdapterSession" name="parameters"/&gt;
     &lt;/wsdl:message&gt;
     &lt;wsdl:portType name="AdapterSessionManager"&gt;
        &lt;wsdl:operation name="initAdapterSession"&gt;
           &lt;wsdl:input message="tns:initAdapterSession" name="initAdapterSession"/&gt;
           &lt;wsdl:output message="tns:initAdapterSessionResponse" name="initAdapterSessionResponse"/&gt;
        &lt;/wsdl:operation&gt;
     &lt;/wsdl:portType&gt;
     &lt;wsdl:binding name="AdapterSessionManagerServiceSoapBinding" type="tns:AdapterSessionManager"&gt;
        &lt;soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/&gt;
        &lt;wsdl:operation name="initAdapterSession"&gt;
           &lt;soap12:operation soapAction="" style="document"/&gt;
           &lt;wsdl:input name="initAdapterSession"&gt;
              &lt;soap12:body use="literal"/&gt;
           &lt;/wsdl:input&gt;
           &lt;wsdl:output name="initAdapterSessionResponse"&gt;
              &lt;soap12:body use="literal"/&gt;
           &lt;/wsdl:output&gt;
        &lt;/wsdl:operation&gt;
     &lt;/wsdl:binding&gt;
     &lt;wsdl:service name="AdapterSessionManagerService"&gt;
        &lt;wsdl:port binding="tns:AdapterSessionManagerServiceSoapBinding" name="AdapterSessionManagerPort"&gt;
           &lt;soap12:address location="http://localhost:8081/adapters/AdapterSessionManager"/&gt;
        &lt;/wsdl:port&gt;
     &lt;/wsdl:service&gt;
  &lt;/wsdl:definitions&gt;
  </code></pre>
  
  <p>This element is intended to be subsituted in SOAP messages with same named elements defined in another namespaces. Here is an example of such definition:</p>
  
  <pre><code>&lt;schema targetNamespace="http://companyname.org/adapter1/" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:inptypns="http://companyname.org/" xmlns:tns="http://companyname.org/adapter1/"&gt;
     &lt;import namespace="http://companyname.org/"/&gt;
     &lt;element name="paramName" substitutionGroup="inptypns:paramName" type="tns:AtomicParamNameType"/&gt;
     &lt;simpleType name="AtomicParamNameType"&gt;
        &lt;restriction base="string"&gt;
           &lt;enumeration value="foo"/&gt;
           &lt;enumeration value="bar"/&gt;
        &lt;/restriction&gt;
     &lt;/simpleType&gt;
  &lt;/schema&gt;
  </code></pre>
  
  <p>Here is Java code implementing this web-service including code generated by wsimport:</p>
  
  <pre><code>@WebService(wsdlLocation = "WEB-INF/wsdl/AdapterSessionManager.wsdl")
  @BindingType(SOAPBinding.SOAP12HTTP_BINDING)
  public class AdapterSessionManager {
  
      @WebMethod
      public Long initAdapterSession(
              @WebParam(name = "adapterId")
              @XmlElement(required = true)
              Long adapterId,
  
              @WebParam(name = "callbackURL")
              @XmlElement(required = true)
              URL callbackURL,
  
              @WebParam
              @XmlElement(required = true)
              AdapterInputDataType adapterInputData
      ) {...}
  }
  
  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlType(name = "AdapterInputDataType", propOrder = {
      "atomicParam"
  })
  public class AdapterInputDataType {
  
      protected List&lt;AtomicParamType&gt; atomicParam;
  
      public List&lt;AtomicParamType&gt; getAtomicParam() {
          if (atomicParam == null) {
              atomicParam = new ArrayList&lt;AtomicParamType&gt;();
          }
          return this.atomicParam;
      }
  
  }
  
  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlType(name = "AtomicParamType", propOrder = {
      "paramName",
      "paramValue"
  })
  public class AtomicParamType {
  
      @XmlElementRef(name = "paramName", namespace = "http://companyname.org/", type = JAXBElement.class)
      protected JAXBElement&lt;?&gt; paramName;
      @XmlElement(required = true)
      protected String paramValue;
  
      public JAXBElement&lt;?&gt; getParamName() {
          return paramName;
      }
  
      public void setParamName(JAXBElement&lt;?&gt; value) {
          this.paramName = value;
      }
  
      public String getParamValue() {
          return paramValue;
      }
  
      public void setParamValue(String value) {
          this.paramValue = value;
      }
  }
  
  @XmlRegistry
  public class ObjectFactory {
  
      private final static QName _ParamName_QNAME = new QName("http://companyname.org/", "paramName");
  
      public ObjectFactory() {
      }
  
      public AtomicParamType createAtomicParamType() {
          return new AtomicParamType();
      }
  
      public AdapterInputDataType createAdapterInputDataType() {
          return new AdapterInputDataType();
      }
  
      @XmlElementDecl(namespace = "http://companyname.org/", name = "paramName")
      public JAXBElement&lt;String&gt; createParamName(String value) {
          return new JAXBElement&lt;String&gt;(_ParamName_QNAME, String.class, null, value);
      }
  }
  
  @XmlType(name = "AtomicParamNameType", namespace = "http://companyname.org/adapter1/")
  @XmlEnum
  public enum AtomicParamNameType {
  
      @XmlEnumValue("foo")
      FOO("foo"),
      @XmlEnumValue("bar")
      BAR("bar");
      private final String value;
  
      AtomicParamNameType(String v) {
          value = v;
      }
  
      public String value() {
          return value;
      }
  
      public static AtomicParamNameType fromValue(String v) {
          for (AtomicParamNameType c: AtomicParamNameType.values()) {
              if (c.value.equals(v)) {
                  return c;
              }
          }
          throw new IllegalArgumentException(v);
      }
  
  }
  
  @XmlRegistry
  public class ObjectFactory {
  
      private final static QName _ParamName_QNAME = new QName("http://companyname.org/adapter1/", "paramName");
  
      public ObjectFactory() {
      }
  
      @XmlElementDecl(namespace = "http://companyname.org/adapter1/", name = "paramName", substitutionHeadNamespace = "http://companyname.org/", substitutionHeadName = "paramName")
      public JAXBElement&lt;AtomicParamNameType&gt; createParamName(AtomicParamNameType value) {
          return new JAXBElement&lt;AtomicParamNameType&gt;(_ParamName_QNAME, AtomicParamNameType.class, null, value);
      }
  
  }
  </code></pre>
  
  <p>I'm testing service with the following SOAP-request:</p>
  
  <pre><code>&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://companyname.org/" xmlns:ans="http://companyname.org/adapter1/"&gt;
     &lt;soapenv:Header/&gt;
     &lt;soapenv:Body&gt;
        &lt;ws:initAdapterSession&gt;
           &lt;adapterId&gt;123&lt;/adapterId&gt;
           &lt;callbackURL&gt;http://callback&lt;/callbackURL&gt;
           &lt;adapterInputData&gt;
              &lt;atomicParam&gt;
                 &lt;ans:paramName&gt;foo&lt;/ans:paramName&gt;
                 &lt;paramValue&gt;hello&lt;/paramValue&gt;
              &lt;/atomicParam&gt;
           &lt;/adapterInputData&gt;
        &lt;/ws:initAdapterSession&gt;
     &lt;/soapenv:Body&gt;
  &lt;/soapenv:Envelope&gt;
  </code></pre>
  
  <p>I have the following UnmarshallException when an application server receives the request:</p>
  
  <blockquote>
    <p>javax.xml.bind.UnmarshalException: unexpected element
    (uri:"<a href="http://companyname.org/adapter1/" rel="nofollow">http://companyname.org/adapter1/</a>", local:"paramName"). Expected
    elements are &lt;{<a href="http://companyname.org/" rel="nofollow">http://companyname.org/</a>}paramName>,&lt;{}paramValue></p>
  </blockquote>
  
  <p>Looks like JAXB is unaware of paramName substitution defined in <code>http://companyname.org/adapter1/</code> namespace. But I can't imagine why JAXB behaves in such a way. Where is my mistake? Any ideas?</p>