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)