Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Frequently Asked Questions

Table of Contents
maxLevel4
minLevel2

...

General

Can CXF run with JDK 1.7?

...

  1. The "JAX-WS" standard way to do this is to write a SOAP Handler that will add the headers to the SOAP message and register the handler on the client/server. This is completely portable from jax-ws vendor to vendor, but is also more difficult and can have performance implications. You have to handle the conversion of the JAXB objects to XML yourself. It involves having the entire soap message in a DOM which breaks streaming. Requires more memory. etc... However, it doesn't require any changes to wsdl or SEI interfaces.
  2. JAX-WS standard "java first" way: if doing java first development, you can just add an extra parameter to the method and annotate it with @WebParam(header = true). If it's a response header, make it a Holder and add the mode = Mode.OUT to @WebParam.
  3. wsdl first way: you can add elements to the message in the wsdl and then mark them as soap:headers in the soap:binding section of the wsdl. The wsdl2java tool will generate the @WebParam(header = true) annotations as above. With CXF, you can also put the headers in their own message (not the same message as the request/response) and mark them as headers in the soap:binding, but you will need to pass the -exsh true flag to wsdl2java to get the paramters generated. This is not portable to other jax-ws providers. Processing headers from other messages it optional in the jaxws spec.
  4. CXF proprietary way: In the context (BindingProvider.getRequestContext() on client, WebServiceContext on server), you can add a List<org.apache.cxf.headers.Header> with the key Header.HEADER_LIST. The headers in the list are streamed at the appropriate time to the wire according to the databinding object found in the Header object. Like option 1, this doesn't require changes to wsdl or method signatures. However, it's much faster as it doesn't break streaming and the memory overhead is less.
Code Block
languagejava

List<Header> headers = new ArrayList<Header>();
Header dummyHeader = new Header(new QName("uri:org.apache.cxf", "dummy"), "decapitated",
                                new JAXBDataBinding(String.class));
headers.add(dummyHeader);

//server side:
context.getMessageContext().put(Header.HEADER_LIST, headers);

//client side:
((BindingProvider)proxy).getRequestContext().put(Header.HEADER_LIST, headers);

...

For the client side

Code Block
xml
xml

    <jaxws:client name="{http://apache.org/hello_world_soap_http}SoapPort"
        createdFromAPI="true">
        <jaxws:properties>
            <entry key="schema-validation-enabled" value="true" />
        </jaxws:properties>
    </jaxws:client>

You may also do this programmatically:

Code Block

((BindingProvider)port).getRequestContext().put("schema-validation-enabled", "true"); 

For the server side

Code Block
languagexml

    <jaxws:endpoint name="{http://apache.org/hello_world_soap_http}SoapPort"
        wsdlLocation="wsdl/hello_world.wsdl"
        createdFromAPI="true">
        <jaxws:properties>
            <entry key="schema-validation-enabled" value="true" />
        </jaxws:properties>
    </jaxws:endpoint>

...

CXF answer: CXF proxies are thread safe for MANY use cases. The exceptions are:

  • Use of ((BindingProvider)proxy).getRequestContext() - per JAX-WS spec, the request context is PER INSTANCE. Thus, anything set there will affect requests on other threads. With CXF, you can do:

    Code Block
    languagejava
    
    ((BindingProvider)proxy).getRequestContext().put("thread.local.request.context", "true");
    

    and future calls to getRequestContext() will use a thread local request context. That allows the request context to be threadsafe. (Note: the response context is always thread local in CXF)

  • Settings on the conduit - if you use code or configuration to directly manipulate the conduit (like to set TLS settings or similar), those are not thread safe. The conduit is per-instance and thus those settings would be shared. Also, if you use the FailoverFeature and LoadBalanceFeatures, the conduit is replaced on the fly. Thus, settings set on the conduit could get lost before being used on the setting thread.

...

Reason: When using Spring AOP, spring injects a proxy to the bean into CXF instead of the actual bean. The Proxy does not have the annotations on it (like the @WebService annotation) so we cannot query the information directly from the object like we can in the non-AOP case. The "fix" is to also specify the actual serviceClass of the object in the spring config:

Code Block
languagexml

<jaxws:server 
      id="myService" 
      serviceClass="my.package.MyServiceImpl" 
      serviceBean="#myServiceImpl" 
      address="/MyService" /> 

or:

Code Block
xml
languagexml

<jaxws:endpoint
      id="myService" 
      implementorClass="my.package.MyServiceImpl" 
      implementor="#myServiceImpl" 
      address="/MyService" />