Here are some of the key concepts in CXF:


this is CXF’s pluggable approach to configure how it maps between XML and Java objects, and is usually one of:


this is CXF’s way of mapping Java classes to/from a WSDL; it can be one of:

  • JAXWS - where CXF will read JAX-WS annotations (e.g. @javax.jws.WebService) on the interface to set namespaces, operation names and parameter names.
  • Simple - where a simple interface (with no annotations) can be mapped to/from a WSDL. This means that CXF will make guesses at operation names and namespaces based on the method names and package of the interface.
Service Class / Service Endpoint Interface (JAX-WS)

This is a Java interface which maps to a portType in a WSDL. It defines the service’s operations, input and output messages, and is annotated with @WebService.

  • e.g. @WebService(targetNamespace = "", name = "CustomerService")


Generating client classes from a WSDL

Add the cxf-codegen-plugin to your Maven POM plugin configuration and bind the wsdl2java goal to Maven’s generate-sources phase. The classes will be generated in target/generated-sources/cxf by default:


CXF as Client - Invoking an operation using CXF

You’ll need:

  • Java classes generated from your target service, with JAX-WS annotations.
  • This Maven dependency: org.apache.cxf:cxf-rt-frontend-jaxws.
// This Factory will create beans which can understand JAX-WS annotations
JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();

// This Factory creates a client for the service
ClientFactoryBean clientBean = proxyFactory.getClientFactoryBean();

// Configure
clientBean.setServiceClass(BookService.class); // This should be the `interface` generated from the WSDL

BookService bookService = (BookService) proxyFactory.create();

// Invoke an operation named `GetAllBooks`
GetAllBooksResponse result = bookService.getAllBooks(new GetAllBooks());

CXF with Camel

To use CXF in Apache Camel, use the CXF component. The component can be configured to use one of the following data formats:

  • POJO (the default in Camel) - a Java object representation of the XML payload
  • MESSAGE - the raw message received from the transport layer; i.e. the untouched, unparsed, raw SOAP XML (including headers, etc.)
  • PAYLOAD - the message payload; i.e. the contents of soap:Body

    • This needs a serviceClass, which should be the fully-qualified class name of the interface, e.g. annotated with @WebService(targetNamespace = "", name = "MyService")

Exposing a CXF endpoint in Camel on Spring Boot

Add to the POM:

<!-- Registers a CXF servlet for exposing web services at path: /services/ -->

And a sample XML DSL Camel route:

<beans xmlns=""

    <camelContext id="camel" xmlns="">
        <route id="inboundRoute">
            <from uri="cxf:/SimpleService?wsdlURL=/wsdl/myService.wsdl&dataFormat=MESSAGE"/>
            <log message="Received message at mock SOAP Service"/>
            <log message="${body}" loggingLevel="DEBUG"/>


Now the service should be available at http://localhost:8080/services/SimpleService

In the logs, look out for:

o.s.b.w.servlet.ServletRegistrationBean  : Servlet CXFServlet mapped to [/services/*]

Explicitly configuring the namespaces on output

CXF will usually try to create a default namespace and assign its own prefixes. But if a legacy client doesn’t understand these, or you need more control over the output (response) from a CXF endpoint, then you can configure CXF explicitly. Here is an example of how to do it in Camel with Spring XML:

<!-- Configure the CXF endpoint manually here so that we have a bit more control over it -->
<cxf:cxfEndpoint id="customerEndpoint"
        <!-- Manually set the prefixes of namespaces in the output -->
        <entry key="">
                <entry key="ns0" value=""/>
                <entry key="ns1" value=""/>
                <entry key="env" value=""/>
        <!-- This property will prevent CXF from setting a default namespace where it can -->
        <entry key="disable.outputstream.optimization" value="true"/>

Notes on this example:

  • Make sure that xmlns:cxf="" is added to the namespace definitions in the XML.
  • The property disable.outputstream.optimization is the key thing here and causes CXF to use namespace prefixes explicitly in the response, rather than trying to assign some elements to a default namespace.


CXF & Camel: “serviceClass must be specified”

  • When wsdlURL option is used without serviceClass, the serviceName and portName (endpointName for Spring configuration) options MUST be provided

CXF: “org.apache.cxf.binding.soap.SoapFault: Message part {}getAllBooks was not recognized. (Does it exist in service WSDL?)”

  • You are most likely using a ClientProxyFactoryBean; switch to a JaxWsProxyFactoryBean (the JAXWS ‘frontend’) so that CXF can understand JAX-WS annotations.

    • Observe that the namespace and operation name given in the log line does not exactly match the namespace and operation in the WSDL.
    • CXF is trying to create its own requests from the package name and method in the service class (interface), rather than using the namespace and operation names defined in JAX-WS annotations.

CXF/JAXWS: “ Cannot find any registered HttpDestinationFactory from the Bus.”

  • Your endpoint’s address is an absolute URL (has a hardcoded http: at the start of it). Change it to a relative URL, to allow CXF to use whatever web server is available (e.g. Tomcat, Undertow)
  • You’re trying to create a service (e.g. Endpoint.publish(...)) but there is no HTTP transport for CXF on the classpath. Add cxf-rt-transports-http-jetty as a dependency. This will allow CXF to use Jetty to host your service.