Building SalesForce client stubs using CXF and Maven

As part of a project at work we’ve been migrating from using ANT scripts and maintaining our libraries manually to using maven both for the build and for library/dependency management.  As part of that project we have also been updating our libraries which some haven’t been updated in 4 years.  We have also decided to finally move off of Apache Axis for our web services both client and server services.  We decided on using JAX-WS and CXF specifically as the implementation.  The transition was not as smooth as I was hoping and I thought I’d post what worked for our situation.

The first thing is downloading our enterprise wsdl file and generating our client stubs.  In maven there is a cxf plugin for this purpose.  Below is a snippet from our POM.

...
<plugins>
...
<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-codegen-plugin</artifactId>
  <version>${cxf.version}</version>
  <dependencies>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-bindings-soap</artifactId>
      <version>${cxf.version}</version>
    </dependency>
  </dependencies>
  <executions>
    <execution>
     <id>generate-sources</id>
     <phase>generate-sources</phase>
     <configuration>
       <sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
       <wsdlOptions>
         <wsdlOption>
           <wsdl>${basedir}/src/main/resources/enterprise.wsdl</wsdl>
           <wsdlLocation>classpath:enterprise.wsdl</wsdlLocation>
           <extraargs>
             <extraarg>-b</extraarg>
             <extraarg>${basedir}/src/main/resources/javabindings.xml</extraarg>
             <extraarg>-autoNameResolution</extraarg>
             <extraarg>-exsh</extraarg>
             <extraarg>true</extraarg>
           </extraargs>
         </wsdlOption>
       </wsdlOptions>
     </configuration>
     <goals>
       <goal>wsdl2java</goal>
     </goals>
   </execution>
  </executions>
</plugin>
...
</plugins>
...

The reason for the dependency of cxf-rt-bindings-soap is because the exsh = true was not working until I included that dependency. The exsh was enabled so I had access to the headers. Unfortunately I was unable to cast to WSBindingProvider so I had to enable this option. I was unable to get the class loader to load the proper jars in the order I needed to avoid this for the container I was using. If you can avoid using exsh I’d recommend doing it, but in my case I had to enable it.

The javabindings.xml file was required for jaxb, so I didn’t need to call getValue or setValue on the SalesForce model objects.

<jaxb:bindings version="2.1" 
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
   <jaxb:globalBindings generateElementProperty="false"/> 
</jaxb:bindings>

The -autoNameResolution was required for SalesForce or you get name conflicts when attempting to build the client stubs. The version of cxf we were using is 2.4.2. Hopefully this will be helpful to someone else that might be building there web services in a similar manner.


Comments are closed.