Code Generation with Maven CXF Plugin

August 31st 2018 Apache CXF Maven Java

Apache CXF is a common choice for calling SOAP web services from Java. It's most convenient to use when you generate proxy client classes from the web service WSDL file. There's a command line tool available for that but if you don't want to put the generated sources in source control, you'll probably prefer the Maven plugin.

It's pretty easy to set up. First you add the CXF dependencies to your pom.xml file:

<properties>
  <cxf.version>3.2.5</cxf.version>
</properties>

<dependencies>
  <dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>${cxf.version}</version>
  </dependency>
</dependencies>

Then you're ready to add the plugin to your build:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-codegen-plugin</artifactId>
      <version>${cxf.version}</version>
      <executions>
        <execution>
          <id>generate-sources</id>
          <phase>generate-sources</phase>
          <configuration>
            <wsdlOptions>
              <wsdlOption>
                <wsdl>${basedir}/src/main/resources/wsdl/service1.wsdl</wsdl>
              </wsdlOption>
            </wsdlOptions>
          </configuration>
          <goals>
            <goal>wsdl2java</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

To my surprise the build failed with the following error:

[ERROR] Failed to execute goal org.apache.cxf:cxf-codegen-plugin:3.2.5:wsdl2java (generate-sources) on project maven-cxf-plugin: Execution generate-sources of goal org.apache.cxf:cxf-codegen-plugin:3.2.5:wsdl2java failed: Rpc/encoded wsdls are not supported with CXF -> [Help 1]

After some research I discovered that RPC/Encoded web services are an older version version of SOAP web services which is therefore not supported by Apache CXF. It surprised me that the web service I needed to call would use such an old standard, therefore I wanted to check by myself if that's true.

After I found an article describing the differences between the older RPC/literal and the newer document/literal web services, I could confirm that my WSDL file described a document/literal web service. Just to be sure, I tried generating the proxy for it using the Apache CXF command line tool. It succeeded.

Obviously, something else was causing the problem for the Maven plugin. After a lot of trial and error, I finally got to the bottom of it. There was another WSDL file in the same folder and that one was for an RPC/literal web service. The plugin failed because it was trying to process it although the full path to my WSDL path in the configuration didn't point to it in any way.

I observed that the plugin was trying to process all the files with .wsdl extension in the folder containing the file I specified:

  • If they were all supported (i.e. they were document/literal web services), it succeeded and created proxy client classes for all of them.

  • If any of them where unsupported (i.e. they were RPC/literal web services), it failed.

Interestingly enough, if I moved all the WSDL files one directory higher (i.e. in the root resources folder), the plugin correctly processed only the single file specified and didn't fail because of unsupported files in the same directory anymore.

Based on these findings, I could fix the problem by either putting my file in a different folder or by moving all the files to the root resources folder. Since I wasn't fond of either option, I did some more research and experimenting.

I managed to find another configuration syntax in the Maven plugin documenation which worked as expected and didn't cause the processing of all WSDL files in my folder:

<configuration>
  <wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot>
  <includes>
    <include>documentService1.wsdl</include>
  </includes>
</configuration>

I'm not sure, why it makes a difference, but I'm glad that the bug I encountered doesn't manifest itself when using this syntax.

Copyright
Creative Commons License