Gradle Plug-in: WSDL to Java Code Generation

Last updated on April 11, 2024

It didn’t take long for me to fall in love with Gradle. Once I was introduced to it, I never looked back. It was the same with Ant as I transitioned from Make. But, Gradle is different. I always felt building was necessary evil. It was often done way after first code was ever written. This isn’t true with Gradle. Before any code is written, I start every project by setting up my Gradle build. I actually look forward to adding more features to my build. How crazy is that?!

WSDL to Java
Recently, I published one of my old SharePoint API to GitHub. Originally, I had written the build script using Ant for this project. One of the task I had was to take the SharePoint List WSDL and generate the corresponding java soap client classes. This is fairly trivial task in Ant – in fact, axis already provides an ant task. Sure, I could google for Gradle plug-in for WSDL to Java but I wanted to use this opportunity to learn to write my own plug-in. I’ve also been looking to write more Groovy code.

Creating a Custom Gradle Task
gradle buildSrcAll custom Gradle tasks resides under buildSrc at the root of your project. If you are familiar with Gradle multiproject then you will notice that buildSrc is structured like a subproject. In fact, it is a subproject. Since I will be writing my custom task using Groovy, my source file will reside under src/main/groovy. If you wanted to write your custom task in Java, you would create it under src/main/java.

Since my custom task is merely a wrapper for Axis2 class org.apache.axis2.wsdl.WSDL2Java, the build.gradle file will contain the Axis2 dependencies. Note, if your custom task does not require any dependencies besides core java, then you do not need to define the build.gradle file. Here’s my build.gradle file:

repositories {
  mavenCentral()
}

dependencies {
  compile 'org.apache.axis2:axis2:1.6.2'
  compile 'org.apache.axis2:axis2-xmlbeans:1.6.2'
  compile 'org.apache.xmlbeans:xmlbeans:2.6.0'
}

Once the build.gradle has been defined, I create my custom task in Groovy – WSDL2Java.groovy. The below Groovy class is a simple implementation. As you can see, there are no validation checks. It assumes all properties will be set.

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
// since this groovy class has the same name as the axis2 class, alias axis2 class to CodeGen
import org.apache.axis2.wsdl.WSDL2Java as CodeGen

class WSDL2Java extends DefaultTask {
  // source location of the WSDL file
  String wsdlfilename
  // specify the binding type - xmlbeans, adb, or jibx
  String databindingName
  // target location where java classes should be created under
  String targetSourceFolderLocation
  // base package name
  String packageName

  @TaskAction
  def generateJava() {
    String[] args =
      [
        "-o", targetSourceFolderLocation,
        "-p", packageName,
        "-d", databindingName,
        "-or",
        "-uri", wsdlfilename
      ]
    CodeGen.main(args)
  }
}

Here’s how this custom task is called within the project. First, I define a task called “genJavaFromWSDL” with type WSDL2Java – the Groovy class name. Within this custom task, I set all properties. Then, I update the dependency of java compile task to this custom task. This will ensure the java soap client is created before build is trigger.

// define the WSDL2Java task
task genJavaFromWSDL(type: WSDL2Java) {
  wsdlfilename= "$buildDir/../src/main/wsdl/Lists.SP2013.wsdl"
  databindingName='xmlbeans'
  targetSourceFolderLocation= "$buildDir/generated/wsdl/main"
  packageName='com.microsoft.sharepoint'
}

// add prior hook before compile
compileJava.dependsOn genJavaFromWSDL

// add generated wsdl java classes to source dir
sourceSets.main.java.srcDir "$buildDir/generated/wsdl/main/src"
sourceSets.main.java.srcDir "$buildDir/generated/wsdl/main/resources"
Gradle Project

Finally, I add the generated source and resources to the Groovy sourceSet so that the generated sources are properly compiled. It also allows them to appear under Eclipse.