[ 
https://issues.apache.org/jira/browse/CXF-7951?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Aritz Bastida updated CXF-7951:
-------------------------------
    Description: 
According to JAX-WS 2.3 spec (section 2.3.4.3), the async binding differs from 
the sync binding in the handling of in-out and out parameters, namely:
 * *Out:* The part or wrapper child is mapped to a property of the response 
bean.
 * *In/Out:* The part or wrapper child is mapped to a method parameter (no 
holder class) and to a property of the response bean.

In our project we are deploying our services on Weblogic, which includes Metro 
(JAX-WS RI) as JAX-WS implementation. And that requires the above signature for 
the async binding to work. However, CXF does not behave the same way: it 
expects the same input parameters in both bindings (sync and async); that means 
we still have the _Holder_ class and no _ResponseBean_.

As a result, we cannot have the same, portable JAX-WS client that can be used 
either with Metro or CXF, which is what we are striving for...

Take for example, the following WSDL. Note that there are two In-Out SOAP 
headers, along with the body.
{code:xml|title=WSDL|borderStyle=solid}
    <wsdl:message name="readFileRecord_MSGIN">
        <wsdl:part element="readFileRecord:ReadFileRecord_IN" name="request"/>
    </wsdl:message>
    <wsdl:message name="readFileRecord_MSGOUT">
        <wsdl:part element="readFileRecord:ReadFileRecord_OUT" name="response"/>
    </wsdl:message>
    <!-- PortType -->
    <portType name="srv-exp-Bank_PortType">
        <wsdl:operation name="readFileRecord">
            <wsdl:input message="tns:readFileRecord_MSGIN"/>
            <wsdl:output message="tns:readFileRecord_MSGOUT"/>
            <wsdl:fault message="tns:FaultDetail_MSG" name="error"/>
        </wsdl:operation>
    </portType>
    <!-- Binding -->
    <binding name="srv-exp-Bank_Binding" type="tns:srv-exp-Bank_PortType">
        <soap:binding style="document" 
transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="readFileRecord">
            <soap:operation soapAction="readFileRecord"/>
            <wsdl:input>
                <soap:header message="tns:TECabecera_MSG"
                    part="te_header" use="literal"/>
                <soap:header message="tns:TEMetadatos_MSG"
                    part="te_metadata" use="literal"/>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:header message="tns:TECabecera_MSG"
                    part="te_header" use="literal"/>
                <soap:header message="tns:TEMetadatos_MSG"
                    part="te_metadata" use="literal"/>
                <soap:body use="literal"/>
            </wsdl:output>
            <wsdl:fault name="error">
                <soap:fault name="error" use="literal"/>
            </wsdl:fault>
        </wsdl:operation>
    </binding>
{code}
...and, as described above, the mapping to Java differs for Metro and CXF:
{code:java|title=Java interface|borderStyle=solid}
 
@WebMethod(action = "readFileRecord")
@WebResult(name = "ReadFileRecord_OUT", targetNamespace = 
"http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
"response")
public ReadFileRecord_OUT readFileRecord(
@WebParam(name = "ReadFileRecord_IN", targetNamespace = 
"http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
"request")
ReadFileRecord_IN request,
@WebParam(name = "TE_Cabecera", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/cabecera";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_header")
Holder<TE_Cabecera> teHeader,
@WebParam(name = "TE_Metadatos", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/metadatos-2.0";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_metadata")
Holder<TE_Metadatos> teMetadata)
throws TE_Excepcion
;

// CXF
@WebMethod(operationName = "readFileRecord", action = "readFileRecord")
public Response<ReadFileRecord_OUT> readFileRecordAsync(
@WebParam(name = "ReadFileRecord_IN", targetNamespace = 
"http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
"request")
ReadFileRecord_IN request,
@WebParam(name = "TE_Cabecera", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/cabecera";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_header")
Holder<TE_Cabecera> teHeader,
@WebParam(name = "TE_Metadatos", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/metadatos-2.0";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_metadata")
Holder<TE_Metadatos> teMetadata);

// METRO 
@WebMethod(operationName = "readFileRecord", action = "readFileRecord")
public Response<ReadFileRecordResponse> readFileRecordAsync(
@WebParam(name = "ReadFileRecord_IN", targetNamespace = 
"http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
"request")
ReadFileRecord_IN request,
@WebParam(name = "TE_Cabecera", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/cabecera";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_header")
TE_Cabecera teHeader,
@WebParam(name = "TE_Metadatos", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/metadatos-2.0";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_metadata")
TE_Metadatos teMetadata);
{code}
In addition, CXF does not behave as required by the JAX-WS spec when an 
exception is thrown in "async" mode. The cause of ExecutionException is the 
inner exception, typically a checked one (such as ConnectException), instead of 
the required unchecked WebServiceException. This is mandated in section 4.3.3 
of the spec:
{quote}♦ Conformance (Reporting asynchronous errors): If the operation 
invocation fails, an implementation MUST throw a 
java.util.concurrent.ExecutionException from the Response.get method. The cause 
of an ExecutionException is the original exception raised. In the case of a 
Response instance this can only be a WebServiceException or one of its 
subclasses
{quote}
Thank you in advance.

 

  was:
According to JAX-WS 2.3 spec (section 2.3.4.3), the async binding differs from 
the sync binding in the handling of in-out and out parameters, namely:
 * *Out:* The part or wrapper child is mapped to a property of the response 
bean.
 * *In/Out:* The part or wrapper child is mapped to a method parameter (no 
holder class) and to a property of the response bean.

In our project we are deploying our services on Weblogic, which includes Metro 
(JAX-WS RI) as JAX-WS implementation. And that requires the above signature for 
the async binding to work. However, CXF does not behave the same way: it 
expects the same input parameters in both bindings (sync and async); that means 
we still have the _Holder_ class and no _ResponseBean_.

As a result, we cannot have the same, portable JAX-WS client that can be used 
either with Metro or CXF, which is what we are striving for...

Take for example, the following WSDL. Note that there are two In-Out SOAP 
headers, along with the body.
{code:xml|title=WSDL|borderStyle=solid}
    <wsdl:message name="readFileRecord_MSGIN">
        <wsdl:part element="readFileRecord:ReadFileRecord_IN" name="request"/>
    </wsdl:message>
    <wsdl:message name="readFileRecord_MSGOUT">
        <wsdl:part element="readFileRecord:ReadFileRecord_OUT" name="response"/>
    </wsdl:message>
    <!-- PortType -->
    <portType name="srv-exp-Bank_PortType">
        <wsdl:operation name="readFileRecord">
            <wsdl:input message="tns:readFileRecord_MSGIN"/>
            <wsdl:output message="tns:readFileRecord_MSGOUT"/>
            <wsdl:fault message="tns:FaultDetail_MSG" name="error"/>
        </wsdl:operation>
    </portType>
    <!-- Binding -->
    <binding name="srv-exp-Bank_Binding" type="tns:srv-exp-Bank_PortType">
        <soap:binding style="document" 
transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="readFileRecord">
            <soap:operation soapAction="readFileRecord"/>
            <wsdl:input>
                <soap:header message="tns:TECabecera_MSG"
                    part="te_header" use="literal"/>
                <soap:header message="tns:TEMetadatos_MSG"
                    part="te_metadata" use="literal"/>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:header message="tns:TECabecera_MSG"
                    part="te_header" use="literal"/>
                <soap:header message="tns:TEMetadatos_MSG"
                    part="te_metadata" use="literal"/>
                <soap:body use="literal"/>
            </wsdl:output>
            <wsdl:fault name="error">
                <soap:fault name="error" use="literal"/>
            </wsdl:fault>
        </wsdl:operation>
    </binding>
{code}
...and, as described above, the mapping to Java differs for Metro and CXF:
{code:java|title=Java interface|borderStyle=solid}
 
@WebMethod(action = "readFileRecord")
@WebResult(name = "ReadFileRecord_OUT", targetNamespace = 
"http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
"response")
public ReadFileRecord_OUT readFileRecord(
@WebParam(name = "ReadFileRecord_IN", targetNamespace = 
"http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
"request")
ReadFileRecord_IN request,
@WebParam(name = "TE_Cabecera", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/cabecera";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_header")
Holder<TE_Cabecera> teHeader,
@WebParam(name = "TE_Metadatos", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/metadatos-2.0";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_metadata")
Holder<TE_Metadatos> teMetadata)
throws TE_Excepcion
;

// CXF
@WebMethod(operationName = "readFileRecord", action = "readFileRecord")
public Response<ReadFileRecord_OUT> readFileRecordAsync(
@WebParam(name = "ReadFileRecord_IN", targetNamespace = 
"http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
"request")
ReadFileRecord_IN request,
@WebParam(name = "TE_Cabecera", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/cabecera";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_header")
Holder<TE_Cabecera> teHeader,
@WebParam(name = "TE_Metadatos", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/metadatos-2.0";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_metadata")
Holder<TE_Metadatos> teMetadata);

// METRO 
@WebMethod(operationName = "readFileRecord", action = "readFileRecord")
public Response<ReadFileRecordResponse> readFileRecordAsync(
@WebParam(name = "ReadFileRecord_IN", targetNamespace = 
"http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
"request")
ReadFileRecord_IN request,
@WebParam(name = "TE_Cabecera", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/cabecera";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_header")
TE_Cabecera teHeader,
@WebParam(name = "TE_Metadatos", targetNamespace = 
"http://telefonica.com/tran/comarq/cc/metadatos-2.0";, header = true, mode = 
WebParam.Mode.INOUT, partName = "te_metadata")
TE_Metadatos teMetadata);
{code}
Am I missing something here? Shouldn't CXF implement this part of the JAX-WS 
spec?

Thank you in advance.

 


> Async binding not JAX-WS compliant
> ----------------------------------
>
>                 Key: CXF-7951
>                 URL: https://issues.apache.org/jira/browse/CXF-7951
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-WS Runtime
>    Affects Versions: 3.2.6
>            Reporter: Aritz Bastida
>            Priority: Major
>
> According to JAX-WS 2.3 spec (section 2.3.4.3), the async binding differs 
> from the sync binding in the handling of in-out and out parameters, namely:
>  * *Out:* The part or wrapper child is mapped to a property of the response 
> bean.
>  * *In/Out:* The part or wrapper child is mapped to a method parameter (no 
> holder class) and to a property of the response bean.
> In our project we are deploying our services on Weblogic, which includes 
> Metro (JAX-WS RI) as JAX-WS implementation. And that requires the above 
> signature for the async binding to work. However, CXF does not behave the 
> same way: it expects the same input parameters in both bindings (sync and 
> async); that means we still have the _Holder_ class and no _ResponseBean_.
> As a result, we cannot have the same, portable JAX-WS client that can be used 
> either with Metro or CXF, which is what we are striving for...
> Take for example, the following WSDL. Note that there are two In-Out SOAP 
> headers, along with the body.
> {code:xml|title=WSDL|borderStyle=solid}
>     <wsdl:message name="readFileRecord_MSGIN">
>         <wsdl:part element="readFileRecord:ReadFileRecord_IN" name="request"/>
>     </wsdl:message>
>     <wsdl:message name="readFileRecord_MSGOUT">
>         <wsdl:part element="readFileRecord:ReadFileRecord_OUT" 
> name="response"/>
>     </wsdl:message>
>     <!-- PortType -->
>     <portType name="srv-exp-Bank_PortType">
>         <wsdl:operation name="readFileRecord">
>             <wsdl:input message="tns:readFileRecord_MSGIN"/>
>             <wsdl:output message="tns:readFileRecord_MSGOUT"/>
>             <wsdl:fault message="tns:FaultDetail_MSG" name="error"/>
>         </wsdl:operation>
>     </portType>
>     <!-- Binding -->
>     <binding name="srv-exp-Bank_Binding" type="tns:srv-exp-Bank_PortType">
>         <soap:binding style="document" 
> transport="http://schemas.xmlsoap.org/soap/http"/>
>         <wsdl:operation name="readFileRecord">
>             <soap:operation soapAction="readFileRecord"/>
>             <wsdl:input>
>                 <soap:header message="tns:TECabecera_MSG"
>                     part="te_header" use="literal"/>
>                 <soap:header message="tns:TEMetadatos_MSG"
>                     part="te_metadata" use="literal"/>
>                 <soap:body use="literal"/>
>             </wsdl:input>
>             <wsdl:output>
>                 <soap:header message="tns:TECabecera_MSG"
>                     part="te_header" use="literal"/>
>                 <soap:header message="tns:TEMetadatos_MSG"
>                     part="te_metadata" use="literal"/>
>                 <soap:body use="literal"/>
>             </wsdl:output>
>             <wsdl:fault name="error">
>                 <soap:fault name="error" use="literal"/>
>             </wsdl:fault>
>         </wsdl:operation>
>     </binding>
> {code}
> ...and, as described above, the mapping to Java differs for Metro and CXF:
> {code:java|title=Java interface|borderStyle=solid}
>  
> @WebMethod(action = "readFileRecord")
> @WebResult(name = "ReadFileRecord_OUT", targetNamespace = 
> "http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
> "response")
> public ReadFileRecord_OUT readFileRecord(
> @WebParam(name = "ReadFileRecord_IN", targetNamespace = 
> "http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
> "request")
> ReadFileRecord_IN request,
> @WebParam(name = "TE_Cabecera", targetNamespace = 
> "http://telefonica.com/tran/comarq/cc/cabecera";, header = true, mode = 
> WebParam.Mode.INOUT, partName = "te_header")
> Holder<TE_Cabecera> teHeader,
> @WebParam(name = "TE_Metadatos", targetNamespace = 
> "http://telefonica.com/tran/comarq/cc/metadatos-2.0";, header = true, mode = 
> WebParam.Mode.INOUT, partName = "te_metadata")
> Holder<TE_Metadatos> teMetadata)
> throws TE_Excepcion
> ;
> // CXF
> @WebMethod(operationName = "readFileRecord", action = "readFileRecord")
> public Response<ReadFileRecord_OUT> readFileRecordAsync(
> @WebParam(name = "ReadFileRecord_IN", targetNamespace = 
> "http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
> "request")
> ReadFileRecord_IN request,
> @WebParam(name = "TE_Cabecera", targetNamespace = 
> "http://telefonica.com/tran/comarq/cc/cabecera";, header = true, mode = 
> WebParam.Mode.INOUT, partName = "te_header")
> Holder<TE_Cabecera> teHeader,
> @WebParam(name = "TE_Metadatos", targetNamespace = 
> "http://telefonica.com/tran/comarq/cc/metadatos-2.0";, header = true, mode = 
> WebParam.Mode.INOUT, partName = "te_metadata")
> Holder<TE_Metadatos> teMetadata);
> // METRO 
> @WebMethod(operationName = "readFileRecord", action = "readFileRecord")
> public Response<ReadFileRecordResponse> readFileRecordAsync(
> @WebParam(name = "ReadFileRecord_IN", targetNamespace = 
> "http://telefonica.com/gstr/srv/Bank/msg/readFileRecord-v3";, partName = 
> "request")
> ReadFileRecord_IN request,
> @WebParam(name = "TE_Cabecera", targetNamespace = 
> "http://telefonica.com/tran/comarq/cc/cabecera";, header = true, mode = 
> WebParam.Mode.INOUT, partName = "te_header")
> TE_Cabecera teHeader,
> @WebParam(name = "TE_Metadatos", targetNamespace = 
> "http://telefonica.com/tran/comarq/cc/metadatos-2.0";, header = true, mode = 
> WebParam.Mode.INOUT, partName = "te_metadata")
> TE_Metadatos teMetadata);
> {code}
> In addition, CXF does not behave as required by the JAX-WS spec when an 
> exception is thrown in "async" mode. The cause of ExecutionException is the 
> inner exception, typically a checked one (such as ConnectException), instead 
> of the required unchecked WebServiceException. This is mandated in section 
> 4.3.3 of the spec:
> {quote}♦ Conformance (Reporting asynchronous errors): If the operation 
> invocation fails, an implementation MUST throw a 
> java.util.concurrent.ExecutionException from the Response.get method. The 
> cause of an ExecutionException is the original exception raised. In the case 
> of a Response instance this can only be a WebServiceException or one of its 
> subclasses
> {quote}
> Thank you in advance.
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to