Frequently Asked Questions
Table of Contents | ||||
---|---|---|---|---|
|
...
General
Can CXF run with JDK/ Java 9+ (10, 11)?
Yes. CXF will support Java 9-11 with the next 3.3.x release.
Can CXF run with JDK 1.8/Java 8?
Yes. CXF supports Java 8. The latest 3.x version is built using JDK 1.8.
Can CXF run with JDK 1.7/Java 7?
Yes. CXF supports Java 7. Since Java 7 contains the 2.2.x versions of both JAXB and JAX-WS API jars, using CXF with Java 7 is much easier than with Java 6.
Info |
---|
CXF 3.2 no longer supports Java 7 and requires Java 8 or newer. Users are strongly encouraged to start moving to Java 8. |
Frequently Asked Questions
...
Can CXF run with JDK 1.6?
JDK 1.6 incorporates the JAXB reference implementation. However, it incorporates an old version of the RI. CXF does not support this version. As of 1.6_04, this is easy to deal with: you must put the versions of JAXB RI (the 'impl' and 'xjc' jars) that we include with CXF in your classpath. As of this writing, these are version 2.2.10.1.6
Info |
---|
CXF 3.1 no longer supports Java 6 and requires Java 7 or newer. |
Can CXF run with JDK 1.5?
Yes for CXF 2.6.x and older. Keep in mind though that Java 2 SE 5.0 with JDK 1.5 has reached end of life (EOL).
Can CXF run with JDK 1.4?
CXF 2.7.x no longer supports Java 5. In order to upgrade to 2.7.x, you must be using Java 6 (or newer).
Info |
---|
There are no more planned releases for the 2.6.x series of CXF that will support Java 5. Users are strongly encouraged to start moving to Java 7 and to start migrating to newer versions of CXF. |
No. Many of the technologies that CXF is based on require JDK 1.5. JAX-WS, JAXB, etc. all require JDK 1.5 features such as generics and annotations. Note that J2SE 1.4 with JDK 1.4 has reached end of life (EOL).
Can CXF run without the Sun reference SAAJ implementation?
In many cases, CXF can run without an SAAJ implementation. However, some features such as JAX-WS handlers and WS-Security do require an SAAJ implementation. Be By default, CXF ships with the Sun SAAJ implementation, but CXF also supports axis2-saaj version 1.4.1 as an alternative. This can make life easier if you use a non-Sun JDK. When using a Java6 JRE, CXF can also use the SAAJ implementation built into Java.
What's the difference between Apache CXF and Fuse Services Framework?
Fuse Services Framework is a certified distribution of Apache CXF provided by FuseSource. FuseSource does all of its development and bug fixes as part of the Apache CXF community, so there are no functional differences between the two. FuseSource may do more frequent releases than Apache, so it is possible to get bug fixes from a Fuse Services Framework release sooner than from an official Apache CXF release.
Consider what Red Hat has done with Linux. Anyone can build their own Linux distribution (http://www.linuxfromscratch.org/) but few people care to do this because of the effort involved in the maintenance, support, testing, validation, etc. of such an effort. Red Hat provides the world with an easily installable Linux distribution with much value added and enterprise level services and support. FuseSource is very similar to Red Hat Linux insomuch as adding value to quality open source software (Apache ActiveMQ, Apache Camel, Apache Derby, Apache ServiceMix, Jetty, etc.) and providing services, support and training for a vetted version of the software.
Are there commercial offerings of CXF that provide services, support, and additional features?
Several companies provide services, training, documentation, support, etc... on top of CXF. Some of those companies also produce products that are either based on Apache CXF or include Apache CXF. See the Commercial CXF Offerings page for a list of companies and the services they provideFor some additional insight into the FuseSource model and how it works, see Bruce Snyder's blog entry entitled The IONA FUSE Model and It's Benefits to the Community. You can also find additional information about Fuse Services Framework and the FuseSource community at "Why join our community".
Is there an Apache CXF certification program?
...
- 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.
- 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.
- 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.
- 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 | ||
---|---|---|
| ||
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 | ||||
---|---|---|---|---|
| ||||
<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 | ||
---|---|---|
| ||
<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 language java ((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.
- Session support - if you turn on sessions support (see jaxws spec), the session cookie is stored in the conduit. Thus, it would fall into the above rules on conduit settings and thus be shared across threads.
- WS-Security tokens - If use WS-SecureConversation or WS-Trust, the retrieved token is cached in the Endpoint/Proxy to avoid the extra (and expensive) calls to the STS to obtain tokens. Thus, multiple threads will share the token. If each thread has different security credentials or requirements, you need to use separate proxy instances.
For the conduit issues, you COULD install a new ConduitSelector that uses a thread local or similar. That's a bit complex though.
For most "simple" use cases, you can use CXF proxies on multiple threads. The above outlines the workarounds for the others.
The generated wsdl (GET request on the ?wsdl address) doesn't contain the messages, types, portType, etc... What did I do wrong?
Usually this means the wsdl at that address contains the service and binding, but uses a <wsdl:import> element to import another wsdl (usually at ?wsdl=MyService1.wsdl type address) that defines the types, messages, and portType. The cause of this is different targetNamespaces for the Service Interface (mapped to the port type) and the service implementation (mapped to the Service/Binding). By default, the targetNamespace is derived from the package of each of those, so if they are in different packages, you will see this issue. Also, if you define a targetNamespace attribute on the @WebService annotation on one of them, but not the other, you will likely see this as well. The easiest fix is to update the @WebService annotation on BOTH to have the exact same targetNamespace defined.
Spring Related
When using Spring AOP to enable things like transactions and security, the generated WSDL is very messed up with wrong namespaces, part names, etc...
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 | ||
---|---|---|
| ||
<jaxws:server
id="myService"
serviceClass="my.package.MyServiceImpl"
serviceBean="#myServiceImpl"
address="/MyService" />
|
or:
Code Block | ||
---|---|---|
| ||
<jaxws:endpoint
id="myService"
implementorClass="my.package.MyServiceImpl"
implementor="#myServiceImpl"
address="/MyService" />
|
...