1. Overview

The goal of this document is to provide reference documentation for developers utilizing the CXF Codegen Gradle plugin.

1.1. What is CXF Codegen

CXF Codegen is a Gradle plugin port of the Maven plugin. The Gradle plugin offers an API similar to the one offered by the Maven plugin. The API is not a 1:1 port and leans heavily on Gradle idioms and conventions.

1.2. Supported Gradle Versions

The CXF Codegen Gradle plugin supports the following Gradle versions:

  • 5.5.1

  • 5.6.4

  • 6.0.1

  • 6.1.1

  • 6.2.2

  • 6.3

  • 6.4.1

  • 6.5.1

  • 6.6.1

  • 6.7.1

  • 6.8.3

  • 7.0-milestone-2

The plugin is fully tested against the above versions to ensure compatibility. View the source of the functional tests for more details.

Gradle’s configuration cache is supported when using Gradle 6.6 or later.

All examples are written for Gradle 6.8.3. Depending on your Gradle version, you may need to adapt the syntax.

2. Plugin Configuration

2.1. Extension

The plugin contributes a single extension to the project named cxfCodegen.

cxfCodegen { (1)
    wsdl2java { (2)

    }
}
1 Primary entry point to the plugin configuration.
2 WSDL sources container for generating Java. It is a NamedDomainObjectContainer type.

2.2. Dependency Configuration

The plugin creates a configuration named cxfCodegen which can be used to add additional dependencies to the classpath for code generation.

Out-of-the-box, the following dependencies are added (v3.4.2):

  • org.apache.cxf:cxf-core

  • org.apache.cxf:cxf-tools-common

  • org.apache.cxf:cxf-tools-wsdlto-core

  • org.apache.cxf:cxf-tools-wsdlto-databinding-jaxb

  • org.apache.cxf:cxf-tools-wsdlto-frontend-jaxws

  • org.apache.cxf:cxf-tools-wsdlto-frontend-javascript

    • org.apache.cxf:cxf-rt-frontend-simple is excluded.

These are the same dependencies defined in the Maven plugin’s POM.

2.2.1. Managing Dependency Versions

Standard Gradle dependency management can be used to control the included dependency versions.

For example, a resolve rule can be used to downgrade the CXF dependencies:

You will need to ensure the version of CXF dependencies you specify is compatible with the options used. Failure to do so will result in an error during code generation.
Groovy
configurations.cxfCodegen {
    resolutionStrategy.eachDependency {
        if (requested.group == "org.apache.cxf") {
            useVersion "3.2.0"
            because "We need a lower version."
        }
    }
}
Kotlin
configurations.cxfCodegen {
    resolutionStrategy.eachDependency {
        if (requested.group == "org.apache.cxf") {
            useVersion("3.2.0")
            because("We need a lower version.")
        }
    }
}

3. Generating Java Sources

The wsdl2java container can be used to define WSDL sources to generate Java sources.

For each source added to the container a corresponding task will also be created. The created task is of type Wsdl2JavaTask and is a subclass of JavaExec. There is nothing special about the Wsdl2JavaTask type, it primarily a marker type with no additional functionality.

Incremental Build

The JavaExec supports up-to-date checks (aka incremental build). As mentioned above, Wsdl2JavaTask is a subclass of JavaExec and as a result, JavaExec also supports up-to-date checks.

However, depending on how your WSDLs are structured, you may run into scenarios where wsdl2java* tasks are out-of-date.

For each WSDL source, the generated Java source is added to the main source sets.

All Wsdl2JavaTask task types are aggregated to a single task named wsdl2java.

3.1. Minimal Usage

The minimum requirement for generating Java is a single WSDL file.

Groovy
cxfCodegen {
    wsdl2java {
        example {
            wsdl = file("path/to/example.wsdl")
        }
    }
}
Kotlin
cxfCodegen {
    wsdl2java {
        example {
            wsdl.set(file("path/to/example.wsdl"))
        }
    }
}

With the above configuration, the plugin will create a task named wsdl2javaExample and output to build/generated-sources/.

3.2. Options

There are quite a few options that can be specified that alter the generated Java. These are identical to ones offered by the Maven plugin.

Groovy
cxfCodegen {
    wsdl2java {
        example {
            wsdl = file("path/to/first.wsdl")
            outputDir = file("$buildDir/generated-java") (1)
            markGenerated = true (2)
            packageNames = ["com.example", "com.foo.bar"] (3)
            asyncMethods = ["foo", "bar"] (4)
        }
    }
}
1 Change the directory the generated code files are written to.
2 Adds the @Generated annotation to classes.
3 Package names to use for the generated code.
4 Specifies subsequently generated Java class methods to allow for client-side asynchronous calls, similar to enableAsyncMapping in a JAX-WS binding file.
Kotlin
cxfCodegen {
    wsdl2java {
        example {
            wsdl.set(file("path/to/example.wsdl"))
            outputDir.set(file("$buildDir/generated-java")) (1)
            markGenerated.set(true) (2)
            packageNames.set(listOf("com.example", "com.foo.bar")) (3)
            asyncMethods.set(listOf("foo", "bar")) (4)
        }
    }
}
1 Change the directory the generated code files are written to.
2 Adds the @Generated annotation to classes.
3 Package names to use for the generated code.
4 Specifies subsequently generated Java class methods to allow for client-side asynchronous calls, similar to enableAsyncMapping in a JAX-WS binding file.

There are more options available than what is shown above. View the method summary section in the Javadoc for WsdlOption for more details.

3.3. Default Options

You may want to configure options that apply to all WSDL sources. This is easily accomplished using native Gradle functionality.

First define some WSDL sources:

Groovy
cxfCodegen {
    wsdl2java {
        first {
            wsdl = file("path/to/first.wsdl")
        }
        second {
            wsdl = file("path/to/second.wsdl")
        }
        third {
            wsdl = file("path/to/third.wsdl")
        }
    }
}
Kotlin
cxfCodegen {
    wsdl2java {
        first {
            wsdl.set(file("path/to/first.wsdl"))
        }
        second {
            wsdl.set(file("path/to/second.wsdl"))
        }
        third {
            wsdl.set(file("path/to/third.wsdl"))
        }
    }
}

Then configure each one using the configureEach method on the container:

Groovy
cxfCodegen {
    wsdl2java.configureEach {
        markGenerated = true
    }
}
Kotlin
cxfCodegen {
    wsdl2java.configureEach {
        markGenerated.set(true)
    }
}

3.4. Java 9+

If you are using Java 9+, you can use the cxfCodegen configuration to add back the Java EE modules that were deprecated in Java 9 and eventually removed in Java 11. Refer to JEP 320 for more details.

Groovy
dependencies {
    cxfCodegen "jakarta.xml.ws:jakarta.xml.ws-api:2.3.3" (1)
    cxfCodegen "jakarta.annotation:jakarta.annotation-api:1.3.5" (2)
}
1 Replacement for javax.xml.ws.Service
2 Replacement for javax.annotation.Resource
Kotlin
dependencies {
    cxfCodegen("jakarta.xml.ws:jakarta.xml.ws-api:2.3.3") (1)
    cxfCodegen("jakarta.annotation:jakarta.annotation-api:1.3.5") (2)
}
1 Replacement for javax.xml.ws.Service
2 Replacement for javax.annotation.Resource

The above is just an example. Depending on your usage, there may be more dependencies required.

3.5. Logging

Without any additional configuration, when executing any wsdl2java tasks, the following lines will be printed to the console:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

To enable logging for Apache CXF, include a SLF4J binding and logging framework. A Logback example is shown below.

Groovy
dependencies {
    cxfCodegen "ch.qos.logback:logback-classic:1.2.3"
}
Kotlin
dependencies {
    cxfCodegen("ch.qos.logback:logback-classic:1.2.3")
}

With the above, you should now start to see a plethora of logs as shown below.

22:14:05.833 [main] DEBUG org.apache.cxf.common.logging.LogUtils - Using org.apache.cxf.common.logging.Slf4jLogger for logging.
22:14:05.967 [main] DEBUG org.apache.cxf.tools.wsdlto.core.PluginLoader - Loading plugin jar:file:~/.gradle/caches/modules-2/files-2.1/org.apache.cxf/cxf-tools-wsdlto-databinding-jaxb/3.4.0/.../cxf-tools-wsdlto-databinding-jaxb-3.4.0.jar!/META-INF/tools-plugin.xml
22:14:06.043 [main] DEBUG org.apache.cxf.tools.wsdlto.core.PluginLoader - Found 1 databindings in <jaxb> plugin.
22:14:06.043 [main] DEBUG org.apache.cxf.tools.wsdlto.core.PluginLoader - Loading <jaxb> databinding from <jaxb> plugin.
22:14:06.043 [main] DEBUG org.apache.cxf.tools.wsdlto.core.PluginLoader - Loading plugin jar:file:~/.gradle/caches/modules-2/files-2.1/org.apache.cxf/cxf-tools-wsdlto-frontend-jaxws/3.4.0/.../cxf-tools-wsdlto-frontend-jaxws-3.4.0.jar!/META-INF/tools-plugin.xml

---- snip

22:14:06.043 [main] DEBUG org.apache.velocity - Initializing Velocity, Calling init()...
22:14:06.043 [main] DEBUG org.apache.velocity - Starting Apache Velocity v2.2
22:14:06.043 [main] DEBUG org.apache.velocity - Default Properties resource: org/apache/velocity/runtime/defaults/velocity.properties

3.5.1. Disable Logs

Logs from Apache CXF can be disabled by specifying a null logger for each Wsdl2JavaTask task type as JVM argument.

Groovy
import io.mateo.cxf.codegen.wsdl2java.Wsdl2JavaTask

tasks.withType(Wsdl2JavaTask).configureEach {
    jvmArgs = ["-Dorg.apache.cxf.Logger=null"]
}
Kotlin
import io.mateo.cxf.codegen.wsdl2java.Wsdl2JavaTask

tasks.withType(Wsdl2JavaTask::class).configureEach {
    jvmArgs = listOf("-Dorg.apache.cxf.Logger=null")
}

Logs from Apache Velocity unfortunately cannot be disabled. However, you can specify a log configuration that essentially overrides all logging levels. For example, an empty Logback configuration will silence all logs:

logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
</configuration>
Groovy
import io.mateo.cxf.codegen.wsdl2java.Wsdl2JavaTask

tasks.withType(Wsdl2JavaTask).configureEach {
    jvmArgs = ["-Dlogback.configurationFile=logback.xml"]
}
Kotlin
import io.mateo.cxf.codegen.wsdl2java.Wsdl2JavaTask

tasks.withType(Wsdl2JavaTask::class).configureEach {
    jvmArgs = listOf("-Dlogback.configurationFile=logback.xml")
}