Java web services: Introducing CXF

Learn about another web services framework from the Apache Software Foundation

The Apache CXF web services stack supports JAXB 2.x data binding (along with some alternative data bindings) and JAX-WS 2.x service configuration. Like the Metro JAXB/JAX-WS alternative discussed in earlier columns, CXF uses XML files to extend the JAX-WS configuration information. In this article, Java web services series author Dennis Sosnoski looks into the basics of working with CXF for client and server development.

Share:

Dennis Sosnoski, Architecture Consultant and Trainer, Sosnoski Software Solutions, Inc.

Author photoDennis Sosnoski is a consultant and trainer specializing in Java-based XML and Web services. His professional software development experience spans more than 30 years, with the last 10 focused on server-side XML and Java technologies. Dennis is the lead developer of the open source JiBX XML Data Binding framework and the associated JiBX/WS Web services framework, as well as a committer on the Apache Axis2 Web services framework. He was also one of the Expert Group members for the JAX-WS 2.0 and JAXB 2.0 specifications. The material for the Java Web Services series is based on Dennis' training classes.



09 February 2010

Also available in Chinese Russian Japanese Portuguese Spanish

CXF is another web services stack from the Apache Software Foundation, the same group behind the Axis2 stack. Even though they come from the same organization, Axis 2 and CXF take very different approaches to how web services are configured and delivered. In this article, you'll learn the basics of using JAXB 2.x and JAX-WS 2.x for web services work with CXF, and you'll see how CXF compares to the other JAXB/JAX-WS stacks — Axis2 and Metro — discussed in prior articles.

CXF basics compared

In terms of the user interface, CXF has a lot in common with the Axis2 and Metro web service stacks. All three stacks allow you either to start from existing Java™ code and build a web service, or start from a WSDL web service description and generate Java code to use or implement the service. And like the other stacks, CXF models service operations as method calls and service port types as interfaces.

About this series

Web services are a crucial part of Java technology's role in enterprise computing. In this series of articles, XML and web services consultant Dennis Sosnoski covers the major frameworks and technologies that are important to Java developers using web services. Follow the series to stay informed of the latest developments in the field and aware of how you can use them to aid your programming projects.

Like Axis2, but unlike Metro, CXF allows you to choose between different data-binding technologies. CXF support for JAXB 2.x data binding is on par with Metro and superior to Axis2 because it allows you to use JAXB customizations when generating code from WSDL (Axis2 does not). CXF also lets you use other data-binding approaches, though the support for them is not as well developed as in Axis2 — in particular, you can generate code from WSDL with CXF only if you're using JAXB or XMLBeans data binding.

The preferred service-configuration technique (or frontend, in CXF terminology) used with CXF is JAX-WS 2.x annotations, generally supplemented by XML configuration files. Support for JAX-WS annotations in CXF is on par with Metro, making it much better suited for JAX-WS use than Axis2 (which has some major limitations in using JAX-WS, as discussed in "JAXB and JAX-WS in Axis2"). As with other JAX-WS implementations, CXF requires the service WSDL to be available to the client at run time.

Like the other stacks, CXF uses request and response processing flows composed of configurable components. CXF calls the components intercepters, rather than handlers, but terminology aside these are equivalent components. Like Metro, CXF comes complete with support for WS-Security and other extension technologies as part of the basic download. Unlike Metro, the CXF JARs are modular — meaning you can pick and choose the JARs to include as part of your application depending on the technologies being used (the /lib/WHICH_JARS file in the CXF installation tells you the particular JARs needed for various common use cases). The downside of this modularity is that you can end up with a long list of specific JARs needed for your application; on the plus side, it allows you to keep down the size of your deployment.

Again like Metro, CXF normally requires you to build a WAR file for your web service rather than deploying potentially many services to a single server installation (the approach used with Axis2). CXF also provides an integrated HTTP server suitable for production use in the form of the Jetty server. This gives you a more flexible and powerful alternative than the simple HTTP server support integrated in Axis2 and Metro.


Sample application

Develop skills on this topic

This content is part of a progressive knowledge path for advancing your skills. See Building and deploying JAX-WS web services

The code download provides a version of the simple library-management service used in previous articles of this series; this one is modified to demonstrate CXF usage. As with the earlier versions, the WSDL service definition defines four operations:

  • getBook retrieves the details for a particular book identified by International Standard Book Number (ISBN).
  • getBooksByType retrieves the details for all books of a particular type.
  • getTypes finds the types of books available.
  • addBook adds a new book to the library.

In "JAXB and JAX-WS in Axis2," you saw how this application worked in Axis2, then in "Introducing Metro," you saw it in Metro. Most of the discussion in the earlier articles also applies to using CXF. The WSDL is identical except for the service name and endpoint address; the generated JAXB data model is the same, and even the generated service classes are identical except for the Java package and the service name used in the JAX-WS annotations.

Client-side usage

Client-side code for the sample application on CXF is identical to using JAX-WS with Axis2 or Metro, and the build steps are very similar: just use the CXF wsdl2java tool in place of the JAX-WS reference implementation wsimport tool. See "JAXB and JAX-WS in Axis2" for details of the code and handling.

Although the client code is the same, there's one significant difference in the client behavior with CXF. By default, CXF prints out an obnoxious amount of logging details to the console. CXF uses Java Logging, so to avoid this output, you need to set a system property to point to a logging properties file with settings changed to output only WARNING or SEVERE information. The Ant build.xml for the sample application does this using the JVM parameter line <jvmarg value="-Djava.util.logging.config.file=${build-dir}/logging.properties"/>.

Server-side usage

The server-side code for the sample application on CXF is also identical to using JAX-WS with Axis2 or Metro, and the build process is very similar to Metro. With Axis2, you prepare the service for deployment by creating a JAR file containing the service and data model classes, then deploy the service by dropping that JAR into the WEB-INF/servicejars directory in an Axis2 server installation. With Metro and CXF, you instead need to create a WAR file containing the service and data model classes, the Metro or CXF library JARs, and a pair of configuration files (one of which is named differently in the two stacks). The WEB-INF/web.xml file configures the actual servlet handling. The version used for the sample application is shown in Listing 1:

Listing 1. Sample application web.xml
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee">
  <display-name>CXFLibrary</display-name>
  <description>CXF Library Service</description>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
      classpath:META-INF/cxf/cxf.xml
      classpath:META-INF/cxf/cxf-extension-soap.xml
      classpath:META-INF/cxf/cxf-servlet.xml
     </param-value>
  </context-param>
  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

The Listing 1 WEB-INF/web.xml file is just a standard servlet configuration file, telling the web application server (such as Tomcat) how to interface to the servlet application. The details are similar to those in the Metro example, though for CXF the <servlet-class> is part of the CXF code and the <listener-class> references a Spring Framework class (see Resources). As with the Metro example, the servlet is configured to process all requests coming to this web application (by the <url-pattern>/</url-pattern> entry).

A separate file, WEB-INF/cxf-servlet.xml, is used to configure CXF to route requests received by the servlet to the service-implementation code and to supply the service WSDL on-demand. This file is shown in Listing 2:

Listing 2. Sample application cxf-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jaxws="http://cxf.apache.org/jaxws"
      xmlns:soap="http://cxf.apache.org/bindings/soap"
      xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
         http://cxf.apache.org/jaxws
         http://cxf.apache.org/schemas/jaxws.xsd">

    <jaxws:endpoint
        id="Processor"
        implementor="com.sosnoski.ws.library.cxf.CXFLibraryImpl"
        wsdlLocation="WEB-INF/wsdl/library.wsdl"
        address="/">
    </jaxws:endpoint>
</beans>

The Listing 2 WEB-INF/cxf-servlet.xml file defines a single endpoint with an implementation class, the pattern to be matched for requests, and a WSDL document location. The WSDL document location is the only optional part of this endpoint definition. If you don't specify a WSDL for a service endpoint in the cxf-servlet.xml file, CXF automatically generates one at run time based on the JAX-WS annotations.

Building and running the sample code

The problems of bundling

As of Java SE 6, the JAXB 2.x and JAX-WS 2.x reference implementation runtimes (except for vendor extensions) became part of the standard Java Runtime Environment (JRE) libraries. This was intended to promote the use of these technologies as Java standards, but it has an unfortunate side-effect: you may need to make a change to your JRE installation to use newer versions of these technologies.

The build.xml used in the sample application download copies the required CXF JAR files directly into the service WAR file. This includes the JAXB and JAX-WS JARs for building with Java SE 5; but when you build with Java SE 6, the build relies on the versions of JAXB and JAX-WS present in the JVM installation. If class-loading conflicts cause problems within the JAXB or JAX-WS code when you use Java SE 6 or later, check if there are any JVM compatibility notes for the CXF distribution you're using.

Before you can try out the sample code, you need to download and install a current version of CXF on your system (see Resources). The sample code was tested with the 2.2.5 release. You also need to edit the build.properties file in the root directory of the unzipped sample-code download to change the value of the cxf-home property to the path to your CXF installation. If you're going to be testing with a server on a different system or port, you may need to change the host-name and host-port.

To build the sample application using the supplied Ant build.xml, open a console to the root directory of the download code and type ant. This will first invoke the CXF wsdl2java tool (included in the CXF distribution), then compile the client and server, and finally package the server code as a WAR. You can then deploy the generated cxf-library.war file to your test server, and finally type ant run on the console to try running the sample client. The sample client runs through a sequence of several requests to the server, printing brief results for each request. As mentioned in Client-side usage, the build configures CXF logging to avoid printing configuration details when running the sample client.


Spring in CXF

Notice the use of Spring Framework bean configurations in the Listing 2 cxf-servlet.xml configuration file. Spring, as you may know, is an open source application framework that includes many component libraries you can use to assemble your applications. The Inversion of Control (IoC) container is the original basis of the Spring Framework. It allows you to link and configure JavaBean-style software components, using Java reflection to access properties of the bean objects at run time.

The Spring IoC container normally uses XML files for the dependency information, and the cxf-servlet.xml file in Listing 2 is an example of such a Spring configuration. The <beans> element is just a wrapper around individual bean configurations. The <jaxws:endpoint> element is such a bean, one that CXF associates with a particular type of object (a org.apache.cxf.jaxws.EndpointImpl instance).

You can specify many other options in the cxf-servlet.xml file beyond those used in this simple example, including message-flow configuration for a service. See the JAX-WS configuration information in the CXF documentation for full details (under Frontends/JAX-WS).

Aside from JAX-WS annotations, Spring is used for all configuration of the CXF stack, including the organization of message flows internal to CXF. Most of the time these configuration details are handled automatically, using XML configuration files included directly in the CXF JARs (see the contextConfigLocation parameter value in the Listing 1 web.xml file to see how these are referenced), but you can override or add to the common flows using your own configuration files. That's not going to be covered directly in this series of articles; you can see the CXF documentation for details.


More CXF ahead

In this article you've seen the basics of using JAXB 2.x data binding and JAX-WS 2.x annotation-based configuration with the CXF web services stack. The same JAXB/JAX-WS code used in earlier articles with the Axis2 and Metro stacks also works in CXF, after only minor changes to the build and using a different deployment-configuration file. This cross-stack compatibility is the main benefit of using JAXB and JAX-WS, since it makes it easy for you to switch between stacks.

There's a lot more to CXF than this simple example shows, and in future articles you'll find out about some of the other features. The next article will look at using WS-Security, so you can see how the CXF implementation compares with Axis2 and Metro.


Download

DescriptionNameSize
Source code for this articlej-jws12.zip16KB

Resources

Learn

Get products and technologies

  • CXF: Download CXF.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Java technology on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology, SOA and web services, Open source
ArticleID=466768
ArticleTitle=Java web services: Introducing CXF
publish-date=02092010