You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Aritz Bastida (JIRA)" <ji...@apache.org> on 2019/06/14 12:48:00 UTC

[jira] [Updated] (CXF-7951) Async binding not JAX-WS compliant

     [ 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)