Uploaded image for project: 'FUSE Mediation Router'
  1. FUSE Mediation Router
  2. MR-348

ClassCastException thrown because camel-cxf CxfConsumer assumes any failed exchange contains a Fault/Throwable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Done
    • Affects Version/s: 2.2.0-fuse-02-00
    • Component/s: None
    • Labels:
      None

      Description

      The attached test case works fine until you cause it to throw a user fault, at this point the route throws the following exception:

      java.lang.ClassCastException: javax.xml.transform.dom.DOMSource cannot be cast to java.lang.Throwable
      at org.apache.camel.component.cxf.CxfConsumer$1.invoke(CxfConsumer.java:99)
      at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
      at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
      at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
      at java.util.concurrent.FutureTask.run(FutureTask.java:138)
      at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
      at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:106)
      at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:243)
      at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:110)
      at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:312)
      at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:276)
      at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:70)
      at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
      at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
      at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
      at org.mortbay.jetty.Server.handle(Server.java:322)
      at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
      at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
      at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
      at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
      at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
      at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
      at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

      This is because CxfConsumer assumes that since the exchange failed the body contains a Fault or Throwable. In the case of this route the body of the exchange is a DOMSource. So when the above happens, the client for the route receives the above exception and not the actual user Fault.

      One potential fix could be to ignore the ClassCastException:

                      // check failure
                      if (camelExchange.isFailed()) {
                          try {
                              // either Fault or Exception
                              Throwable t = (camelExchange.hasOut() && camelExchange.getOut().isFault()) 
                                  ? (Throwable)camelExchange.getOut().getBody() : camelExchange.getException();
                              throw (t instanceof Fault) ? (Fault)t : new Fault(t);
                          } catch (ClassCastException cce) {
                              //ignore
                          }
                      }
      

      though this bypasses Camel's normal error handling a bit, however for this particular use case with the above fix the client then gets the user fault returned to it properly.

      To reproduce build and deploy the Endpoint1 and Route1 projects into Fuse ESB (you need to deploy the camel-nmr and cxf-nmr features), then point SoapUI to http://localhost:10109/endpoints/PersonService?wsdl and generate a request, delete the '?' from between the personId tags and send the request. The client should get back a soap fault with a message of "javax.xml.transform.dom.DOMSource cannot be cast to java.lang.Throwable".

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                willem.jiang Willem Jiang
                Reporter:
                stlewis Stan Lewis
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: