[
https://issues.apache.org/jira/browse/CXF-6050?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14224130#comment-14224130
]
Vladimir Plizga commented on CXF-6050:
--------------------------------------
Thank you for your reply. I've tried 2.7.13 version; you are right, there is no
exception stacktraces in the log anymore but problem with custom fault
deserialization remains the same.
It took some time for me to extract "clean" test case from our big application,
but I've done it. In the attached [^cxf-test.zip] file you can find complete
IntelliJ IDEA source project (including dependent libraries) and according SOAP
UI project for mocking web service. For sources there are also Eclipse project
files but they were not tested.
(on) To reproduce the error the following steps should be taken:
# Open *CXF-Test-soapui-project.xml* from the archive root with SOAP UI and
start *BeeModule MockService* inside it (by default it will bind to
_localhost:8088_)
# Open the source project with IDEA/Eclipse and run the
*ru.apache.cxf.test.Launcher* class.
The latter must make two queries to the mock web service (which is expected to
be on _localhost:8088_ but can be changed in _application.properties_):
- *echo* request (just to check everything is ready to proceed); this must end
up with successful message in console log:
{noformat}
INFO cxf.test.Launcher - Pong: Pong
{noformat}
- *extraBonus* request to reproduce the error. The mock service has been
charged to return a fault that exactly reproduces the fault from real web
service, so it causes the same behavior on the client side:
{noformat}
javax.xml.ws.soap.SOAPFaultException: Remote part returned an error while
getting bonuses
{noformat}
(*r) The point here is that *SOAPFaultException* contains no fields with
application error code ("<code>214</code>") because of deserialization fault
described in this issue's description. Neither regular *Fault_Exception*
returns.
Some more details can be found in catch blocks at _Launcher.java:35,38_.
Hope this will help you to find out the reason and fix it.
P.S. I'm not sure it concerns the problem somehow, but still pay attention to
it - there is one manual change in wsdl2java generated classes, see
_ru/apache/cxf/test/generated/Fault.java:103_.
> NullPointerException while creating custom exception in CXF client
> ------------------------------------------------------------------
>
> Key: CXF-6050
> URL: https://issues.apache.org/jira/browse/CXF-6050
> Project: CXF
> Issue Type: Bug
> Components: JAX-WS Runtime
> Affects Versions: 2.7.6
> Environment: Windows OS with Tomcat servlet container; CXF 2.7.6
> Reporter: Vladimir Plizga
> Labels: client, jaxb, wsdl
> Attachments: Fault.java, Fault_Exception.java, cxf-test.zip
>
>
> As stated in CXF-3763, when server throws an exception which looks like
> {code:xml}
> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
> <soapenv:Body>
> <soapenv:Fault>
> <faultcode>soapenv:Server</faultcode>
> <faultstring>Remote part returned an error while getting
> bonuses</faultstring>
> <detail>
> <fault>
> <faultcode>:214</faultcode>
> <faultstring>Remote part returned an error while getting
> bonuses</faultstring>
> <faultactor>http://www.somhost.ru/appmod#2.0?module</faultactor>
> <detail>
> <common-detail>
> <code>214</code>
> <message>Remote part returned an error while getting
> bonuses</message>
> </common-detail>
> </detail>
> </fault>
> </detail>
> </soapenv:Fault>
> </soapenv:Body>
> </soapenv:Envelope>
> {code}
> , CXF tries to deserialize it into custom Fault object (generated by
> *wsdl2java* in my case) but fails with another internal exception:
> {noformat}
> INFO org.apache.cxf.interceptor.ClientFaultConverter - Exception
> occurred while creating exception: null
> java.lang.NullPointerException
> at
> org.apache.cxf.interceptor.ClientFaultConverter.getConstructor(ClientFaultConverter.java:203)
> at
> org.apache.cxf.interceptor.ClientFaultConverter.processFaultDetail(ClientFaultConverter.java:175)
> at
> org.apache.cxf.interceptor.ClientFaultConverter.handleMessage(ClientFaultConverter.java:79)
> at
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
> at
> org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:113)
> at
> org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
> at
> org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
> at
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
> at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:811)
> at
> org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1590)
> at
> org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1486)
> at
> org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1305)
> at
> org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:50)
> at
> org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:223)
> at
> org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
> at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:623)
> at
> org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
> at
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
> at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:541)
> at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)
> at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377)
> at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330)
> at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
> at
> org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
> ... (some application code)
> {noformat}
> Source code of generated [^Fault.java] and [^Fault_Exception.java] classes is
> attached to the issue.
> (!) I use JAXB mapping so the patch offered in CXF-3763 doesn't help in my
> case because it's applied to *TypeClassInitializer* while my client runs on
> another _ServiceModelVisitor_ descendant - *JAXBContextInitializer* class.
> (i) During debugging of *JAXBContextInitializer* I've found out that every
> time when *begin()* method triggers for a _MessagePartInfo_ describing a
> fault, it immediately returns because *getTypeClass()* on the _part_ returns
> *null* (see _org.apache.cxf.jaxb.JAXBContextInitializer:77_).
> AFAIU the method should continue execution to line 82 where the part would be
> marked as custom exception.
> (+) Some WSDL excerpts
> WSDL Fault message:
> {code:xml}
> <wsdl:message name="Fault">
> <wsdl:part name="fault" element="fault"/>
> </wsdl:message>
> {code}
> XSD Fault element:
> {code:xml}
> <xs:element name="fault">
> <xs:annotation>
> <xs:documentation>Comment describing your root element</xs:documentation>
> </xs:annotation>
> <xs:complexType>
> <xs:sequence>
> <xs:element name="faultcode">...</xs:element>
> <xs:element name="faultstring">...</xs:element>
> <xs:element name="faultactor">...</xs:element>
> <xs:element minOccurs="0" name="detail">...</xs:element>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
> {code}
> Example of WSDL operation description:
> {code:xml}
> <wsdl:operation name="BonusConversionState">
> <wsdl:input name="BonusConversionStateRequest"
> message="tns:BonusConversionStateRequest"/>
> <wsdl:output name="BonusConversionStateResponse"
> message="tns:BonusConversionStateResponse"/>
> <wsdl:fault name="Fault" message="tns:Fault"/>
> </wsdl:operation>
> {code}
> Additional info can be provided if needed.
> Any suggestion on how to workaround the problem would be also appreciated.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)