Web Services with CXF and Eclipse

Watch Out!

This page is out of date, and there is a new approach to developing CXF services with Eclipse! We'll have the details up here as soon as possible.

Introduction

These directions assume that you are familiar with using Eclipse, that you know how to create a war file and that you know how to create a WSDL.

Setup

It is assumed that you have already downloaded and installed Eclipse with version 3.3 or higher. You will also need to download and extract the Apache CXF binary distribution and Apache Tomcat or your favorite web application server.

Updating Eclipse

You will need to install some extra plugins in eclipse for the Web Services in general, and the CXF Web Services specifically. You can easily download the all-in-one package and extract it to your eclipse folder.
Note: The downloaded package is not the latest version. The latest version of STP(SOA Tools Platform) plugin which integrates the new java2ws tool can only support CXF 2.1.* or higher.

Adding CXF runtime in Eclipse

Once you have all your uploads loaded, you'll need to link CXF as your Installed runtime. Click Windows/Preferences/SOA Tools/Installed Runtimes to open an runtime configuration page. In this page click Add button and browse to your directory that contains Apache CXF, then click OK.

Adding Tomcat Server in Eclipse

  • Click Window/Show View/Other.../Server/Servers to open the server view.
  • In the server view, right click and select New/Server/Apache/Tomcat v6.0 Server. Click next button and browse to your directory that contains Tomcat, then click Finish.
  • Now, in the server view, there will be a new tomcat server. Double click the tomcat server to open the configuration page in Editor Part.
  • In the Server Locatiotn part of this configuration page, choose Use Tomcat installation (takes control of Tomcat installation) and modify the Deploy path from wtpwebapps to webapps.
  • There should be an project named Servers in Navigator View. Open the file catalina.properties of this project and add (CXF_Install_Location)/lib/*.jar to the property shared.loader.
  • All finished!

Creating a Project

Java First (Not Recommended)

NOTE: Keep the default directory structure. The automated system gets confused if you change it.

  • Select File/New/Other/SOA Tools/JAX-WS Java First Project
  • Say yes when asked if you want to open the JAX-WS perspective
  • Create an interface for your service:
    package com.cid.simpleservice.service
    
    public interface ScientificCalculator {
       public float squareRoot( float value,float pow);
    }
    
  • Annotate the interface:
    • Right-click class in the Outline View
    • Select JAX-WS Tools/Create Web Service
    • Right-click your method(s) name(s) in the Outline View
    • Select JAX-WS Tools/Create Web Method
  • Save your file. If the Project/Build Automatically has been checked, you should see a new wsdl folder show up in your project directory structure as soon as you save it. Or you can also build your project manually to generate wsdl folder. Within the folder should be a WSDL based upon your interface.

Now you'll need to make some modifications to the automatically generated comments.

  • Click on @WebService, which should be appearing above your interface name. The Annotation Properties should appear
    in the box below your editing window. If not, select Window/Show View/Other. From the pop-up menu, select SOA Tools/@ Annotation Properties.
  • In the Annotation Properties, change javax.jws.soap.SOAPBinding from false to true. This may require you to change other settings. If so, check the CXF documentation for correct values.

After your changes are made and save without any error, a WSDL should appear in the wsdl folder. If it doesn't, use java2wsdl from the CXF package. You can either run it from the command prompt, as an ant task, or from Maven. The
default output directory will be the wsdl directory.

After the WSDL is created, modify to meet your needs. For example, the port is, by default http://localhost:9090/. In addition, leaving the parameter named parameters on the input request is not acceptable to .NET code creation routines.

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="ScientificCalculatorService" targetNamespace="http://service.simpleservice.cid.com/" 
xmlns:ns1="http://service.simpleservice.cid.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  <wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://service.simpleservice.cid.com/" 
attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://service.simpleservice.cid.com/">
<xsd:element name="squareRoot" type="squareRoot"/>
<xsd:complexType name="squareRoot">
<xsd:sequence>
<xsd:element name="arg0" type="xsd:float"/>
<xsd:element name="arg1" type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="squareRootResponse" type="squareRootResponse"/>
<xsd:complexType name="squareRootResponse">
<xsd:sequence>
<xsd:element name="return" type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
  </wsdl:types>
  <wsdl:message name="squareRootResponse">
    <wsdl:part name="squareRootOutput" element="ns1:squareRootResponse">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="squareRoot">
    <wsdl:part name="squareRootInput" element="ns1:squareRoot">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="ScientificCalculator">
    <wsdl:operation name="squareRoot">
      <wsdl:input name="squareRoot" message="ns1:squareRoot">
    </wsdl:input>
      <wsdl:output name="squareRootResponse" message="ns1:squareRootResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="ScientificCalculatorServiceSoapBinding" type="ns1:ScientificCalculator">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="squareRoot">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="squareRoot">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="squareRootResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="ScientificCalculatorService">
    <wsdl:port name="ScientificCalculatorPort" binding="ns1:ScientificCalculatorServiceSoapBinding">
      <soap:address location="http://localhost:8080/JavaFirstTest"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Once your WSDL is set, use it to create your implementation class. Highlight the WSDL and right-click. Select JAX-WS Tools/Generate Code. Select Implementation and, if you're using Ant, select Generate Ant Script. If the Impl file isn't created, you can run wsdl2java using the command line, Ant task or maven.

/**
 * Please modify this class to meet your needs
 * This class is not complete
 */

package com.cid.simpleservice.service;

import java.util.logging.Logger;
import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;


@javax.jws.WebService(name = "ScientificCalculator", serviceName = "ScientificCalculatorService",
                      portName = "ScientificCalculatorPort",
                      targetNamespace = "http://service.simpleservice.cid.com/", 
                      wsdlLocation = "file:wsdl/javaFirstTest.wsdl" ,
		      endpointInterface = "com.cid.simpleservice.service.ScientificCalculator")
                      
public class ScientificCalculatorImpl implements ScientificCalculator {

    private static final Logger LOG = Logger.getLogger(ScientificCalculatorImpl.class.getName());

    /* (non-Javadoc)
     * @see com.cid.simpleservice.service.ScientificCalculator#squareRoot(float  arg0 ,)float  arg1 )*
     */
    public float squareRoot(float arg0,float arg1) { 
        LOG.info("Executing operation squareRoot");
        System.out.println(arg0);
        System.out.println(arg1);
        try {
   
            float _return = 0.0f;
            return _return;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }

}

Note: this last step is why it's suggested that you not use this process. Using java2wsdl, then wsdl2java is not supported at this time by CXF. And, as you've seen some of the automation doesn't work quite right.

Modify your Implementation class to reflect your actual methods.

WSDL First

Create your WSDL. The syntax is beyond the scope of this wiki. But there is a tool within Eclipse for creating one. Just select File/New/Other/Web Services/WSDL. You can validate your WSDL by using wsdl2java with the -validate flag.

Create a new project: File/New/Project/SOA Tools/JAX-WS WSDL First Project. Select your WSDL. Select to create the Implementation and, if you wish, Generate Ant Script. Leave everything checked as shown. If the code isn't automatically generated, run wsdl2java to generate your code.

Modify your implementation classes to reflect your actual methods.

Deploying Project

Building Package

Right click the WSDL file and select Build Package... in popup menu. Then an war file will be generated in the folder build.

Deploying Package

Right click the WSDL file or the war file and select Deploy... in popup menu. In the popup window, select Tomcat Server you just created above. Then click OK.

Starting Service

Start the Tomcat Server in the Server View. If everything is OK, the service of your project should be activated.
Once you deploy your war file, go to: http://<your server>:<port>/<deployment name>/services. You'll see a link to your wsdl file. Click on it and your wsdl should appear.