diff --git a/README.md b/README.md
index 903fb4a..36b27e2 100644
--- a/README.md
+++ b/README.md
@@ -1,378 +1,401 @@
-[![Gradle Plugin Release](https://img.shields.io/badge/Gradle%20plugin-1.6.0-blue.svg?logo=data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MCA2Ni4wNiI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNmZmY7fTwvc3R5bGU+PC9kZWZzPjx0aXRsZT5ncmFkbGUtZWxlcGhhbnQtaWNvbi13aGl0ZS1wcmltYXJ5PC90aXRsZT48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik04NS4xMSw0LjE4YTE0LjI3LDE0LjI3LDAsMCwwLTE5LjgzLS4zNCwxLjM4LDEuMzgsMCwwLDAsMCwyTDY3LDcuNmExLjM2LDEuMzYsMCwwLDAsMS43OC4xMkE4LjE4LDguMTgsMCwwLDEsNzkuNSwyMC4wNkM2OC4xNywzMS4zOCw1My4wNS0uMzYsMTguNzMsMTZhNC42NSw0LjY1LDAsMCwwLTIsNi41NGw1Ljg5LDEwLjE3YTQuNjQsNC42NCwwLDAsMCw2LjMsMS43M2wuMTQtLjA4LS4xMS4wOEwzMS41MywzM2E2MC4yOSw2MC4yOSwwLDAsMCw4LjIyLTYuMTMsMS40NCwxLjQ0LDAsMCwxLDEuODctLjA2aDBhMS4zNCwxLjM0LDAsMCwxLC4wNiwyQTYxLjYxLDYxLjYxLDAsMCwxLDMzLDM1LjM0bC0uMDksMC0yLjYxLDEuNDZhNy4zNCw3LjM0LDAsMCwxLTMuNjEuOTQsNy40NSw3LjQ1LDAsMCwxLTYuNDctMy43MWwtNS41Ny05LjYxQzQsMzItMi41NCw0Ni41NiwxLDY1YTEuMzYsMS4zNiwwLDAsMCwxLjMzLDEuMTFIOC42MUExLjM2LDEuMzYsMCwwLDAsMTAsNjQuODdhOS4yOSw5LjI5LDAsMCwxLDE4LjQyLDAsMS4zNSwxLjM1LDAsMCwwLDEuMzQsMS4xOUgzNS45YTEuMzYsMS4zNiwwLDAsMCwxLjM0LTEuMTksOS4yOSw5LjI5LDAsMCwxLDE4LjQyLDBBMS4zNiwxLjM2LDAsMCwwLDU3LDY2LjA2SDYzLjFhMS4zNiwxLjM2LDAsMCwwLDEuMzYtMS4zNGMuMTQtOC42LDIuNDYtMTguNDgsOS4wNy0yMy40M0M5Ni40MywyNC4xNiw5MC40MSw5LjQ4LDg1LjExLDQuMThaTTYxLjc2LDMwLjA1bC00LjM3LTIuMTloMGEyLjc0LDIuNzQsMCwxLDEsNC4zNywyLjJaIi8+PC9zdmc+)](https://plugins.gradle.org/plugin/com.github.bjornvester.xjc)
-[![GitHub Actions status](https://github.com/bjornvester/wsdl2java-gradle-plugin/workflows/CI/badge.svg)](https://github.com/bjornvester/wsdl2java-gradle-plugin/actions)
-
-# wsdl2java-gradle-plugin
-
-A Gradle plugin for generating Java classes from WSDL files through CXF.
-
-## Requirements and main features
-
-* The plugin requires Gradle 6.7 or later. (Tested with Gradle 6, 7 and 8.)
-* For using the Jakarta namespace (default), the plugin requires Java 17 or greater. For the older javax namespace, you can use Java 8, 11 or 17.
-* It supports the Gradle build cache (enabled by setting `org.gradle.caching=true` in your gradle.properties file).
-* It supports the Gradle configuration cache (enabled by setting `org.gradle.configuration-cache=true` in your gradle.properties file").
-* It supports project relocation for the build cache (e.g. you move your project to a new path, or make a new copy/clone of it).
- This is especially useful in a CI context, where you might clone PRs and/or branches for a repository in their own locations.
- Note, however, that there is an issue in an Apache library called `org.apache.ws.xmlschema:xmlschema-core` that might break this - see below for details.
-* It supports parallel execution (enabled with `org.gradle.parallel=true` in your gradle.properties file), though it does not itself run anything in parallel.
-
-## Configuration
-
-Apply the plugin ID "com.github.bjornvester.wsdl2java" as specific in
-the [Gradle Plugin portal page](https://plugins.gradle.org/plugin/com.github.bjornvester.wsdl2java), e.g. like this:
-
-```kotlin
-plugins {
- id("com.github.bjornvester.wsdl2java") version "2.0"
-}
-```
-
-Put your WSDL and referenced XSD files somewhere in your src/main/resource directory.
-By default, the plugin will create Java classes for all the WSDL files in the resource directory.
-
-The generated code will by default end up in the directory build/generated/sources/wsdl2java folder.
-
-You can configure the plugin using the "wsdl2java" extension like this:
-
-```kotlin
-wsdl2java {
- // Set properties here...
-}
-```
-
-Here is a list of all available properties:
-
-| Property | Type | Default | Description |
-|----------------------------|-----------------------|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| wsdlDir | DirectoryProperty | "$projectDir/src
/main/resources" | The directory holding the WSDL and referenced XSD files to compile. |
-| includes | ListProperty\ | \["**/*.wsdl"] | Inclusion filers (Ant style) for which WSDLs to include. |
-| includesWithOptions | Map\ | \[not set\] | Inclusion filters like above, but with individual options. See below. |
-| generatedSourceDir | DirectoryProperty | "$buildDir/generated
/sources/wsdl2java/java" | The output directory for the generated Java sources.
Note that it will be deleted when running XJC. |
-| bindingFile | RegularFileProperty | \[not set\] | A binding file to use in the schema compiler. |
-| cxfVersion | Provider\ | "4.0.2" for jakarta / 3.5.6 for javax | The version of CXF to use. Use a version >= 4 for `jakarta` and below for `javax`. |
-| useJakarta | Provider\ | true | Set to use the `jakarta` namespace. If false, uses the `javax` namespace. This value also determines the default version of CXF. |
-| verbose | Provider\ | \[not set\] | Enables verbose output from CXF. If not set, it will be be enabled only on the info logging level. |
-| markGenerated | Provider\ | "no" | Adds the @Generated annotation to the generated sources. See below for details as there are some gotchas with this. |
-| generatedStyle | Provider\ | "default" | If using the @Generated annotation, select the type can be overridden by this. See below for details. |
-| suppressGeneratedDate | Provider\ | true | Suppresses generating dates in CXF. Default is true to support reproducible builds and to work with the build cache. |
-| packageName | Provider\ | \[not set\] | Sets the package name for the generated sources |
-| options | ListProperty\ | \[empty\] | Additional options to pass to the tool. See [here](https://cxf.apache.org/docs/wsdl-to-java.html) for details. |
-| addCompilationDependencies | Provider\ | true | Adds dependencies to the `implementation` configuration for compiling the generated sources. These includes `jakarta.xml.ws:jakarta.xml.ws-api`, `jakarta.jws:jakarta.jws-api` and possibly `jakarta.annotation:jakarta.annotation-api`. |
-
-### Configure the CXF version
-
-You can specify the version of CXF used for code generation like this:
-
-```kotlin
-wsdl2java {
- cxfVersion.set("4.0.2")
-}
-```
-
-### Configure included WSDL files
-
-By default, the plugin will find all WSDL files in the `wsdlDir` directory, which defaults to `src/main/resources`.
-It is important that if you change this, you change it to a folder that contain all resources (e.g. both WSDL and XSDs).
-Otherwise, if you make changes to files outside this folder, Gradle will not see them and thus might consider the task
-up-to-date.
-
-The plugin will set the `wsdlLocation` property of the `@WebServiceClient` to the path for the WSDL file relative to
-the `wsdlDir` directory.
-If you change `wsdlDir` in a way where this no longer makes sense, you need to set the option yourself.
-If you have multiple WSDL files, see the section on additional options.
-
-If you have multiple WSDL files and want to only run the tool on some of them, you can use the `includes` property.
-Example:
-
-```kotlin
-// Only if different from the default 'src/main/resources'
-wsdlDir.set(layout.projectDirectory.dir("src/main/wsdl"))
-
-// For Kotlin DSL
-includes.set(
- listOf(
- "src/main/wsdls/MyFirstService.wsdl",
- "src/main/wsdls/MySecondService.wsdl"
- )
-)
-```
-
-```groovy
-// For Groovy DSL
-includes = [
- "src/main/wsdls/MyFirstService.wsdl",
- "src/main/wsdls/MySecondService.wsdl"
-]
-```
-
-### Configure additional options
-
-Besides the options given in the `wsdl2java` extension, you can provide additional options directly to CXF (and XJC)
-through the `options` property:
-
-```kotlin
-// For Kotlin DSL
-includes.set(
- listOf(
- "xjc-no-header",
- "xjc-npa"
- )
-)
-
-// For Groovy DSL
-includes = [
- "xjc-no-header",
- "xjc-npa"
-]
-```
-
-See [here](https://cxf.apache.org/docs/wsdl-to-java.html) for the available options.
-
-#### Configure additional options for individual WSDL files
-
-It is possible to pass options for individual WSDL files.
-This is important especially if you need to explicitly configure the `wsdlLocation` option, as it doesn't make to have
-the same location in all files.
-(But note that if you leave it out, the plugin will guess it based on the file location.)
-
-```kotlin
-// For Kotlin DSL
-includesWithOptions.set(
- mapOf(
- "**/ServiceA.wsdl" to listOf("-wsdlLocation", "https://example.com/service-a?wsdl"),
- "**/ServiceB.wsdl" to listOf("-wsdlLocation", "https://example.com/service-b?wsdl")
- )
-)
-```
-
-```groovy
-// For Groovy DSL
-includes = [
- "**/ServiceA.wsdl": ["-wsdlLocation", "https://example.com/service-a?wsdl"],
- "**/ServiceB.wsdl": ["-wsdlLocation", "https://example.com/service-b?wsdl"]
-]
-```
-
-### Configure the output directory
-
-You can optionally specify the directory for the generated source through the `generatedSourceDir` property, which
-defaults to `$buildDir/generated/sources/wsdl2java/java`.
-Example:
-
-```kotlin
-wsdl2java {
- generatedSourceDir.set(layout.projectDirectory.dir("src/generated/wsdl2java"))
-}
-```
-
-Note that the directory will be wiped completely on each run, so don't put other source files in it.
-
-### Configure binding files
-
-A binding file can be added like this:
-
-```kotlin
-wsdl2java {
- bindingFile.set(layout.projectDirectory.file("src/main/bindings/binding.xjb"))
-}
-```
-
-If you get a warning on maximum enum member size, you can raise the maximum like this:
-
-```xml
-
-
-
-
-
-
-
-
-
-```
-
-If you are using the older `javax` namespace instead of `jakarta`, set the `jxb` attribute to `http://java.sun.com/xml/ns/jaxb` instead and the version to 2.1.
-
-If you like to use the Java Date/Time API instead of the more clunky GregorianCalendar class, you can
-use [threeten-jaxb](https://github.com/threeten-jaxb/threeten-jaxb) library with a binding file like example below.
-
-```kotlin
-dependencies {
- implementation("io.github.threeten-jaxb:threeten-jaxb-core:2.1.0")
-}
-
-wsdl2java {
- bindingFile.set(layout.projectDirectory.file("src/main/bindings/bindings.xjb"))
-}
-```
-
-```xml
-
-
-
-
-
-
-
-
-
-
-
-```
-
-In the above, for `javax`, use version 1.2.0 and the binding attributes to `xmlns="http://java.sun.com/xml/ns/jaxb" version="2.1"`.
-
-Note that at the moment, it is not possible to specify more than one binding file in the extension. If you require this,
-use the `-b` option.
-
-### Configuring package names
-
-The package name for the generated resources can be configured with the `packageName` field:
-
-```kotlin
-wsdl2java {
- packageName.set("com.github.bjornvester.wsdl2java.group1")
-}
-
-```
-
-### Configure encoding
-
-If your WSDL files include non-ANSI characters, you should set the corresponding file encoding in your gradle.properties
-file. E.g.:
-
-```properties
-org.gradle.jvmargs=-Dfile.encoding=UTF-8
-```
-
-If you are on a POSIX operating system (e.g. Linux), you may in addition to this need to set your operating system
-locale to one that supports your encoding.
-Otherwise, Java (and therefore also Gradle and CXF) may not be able to create files with names outside of what your
-default locale supports.
-Especially some Docker images, like the Java ECR images from AWS, are by default set to a locale supporting ASCII only.
-If this is the case for you, and you want to use UTF-8, you could export an environment variable like this:
-
-```shell script
-export LANG=C.UTF-8
-```
-
-### Using javax instead of the jakarta namespace
-
-To use the older javax namespace in the generated files, set the `useJakarta` property to `false.
-
-```kotlin
-wsdl2java {
- useJakarta.set(false)
-}
-```
-
-### Activating (third party) XJC plugins
-
-To use third party plugins for the underlying XJC tool, supply the relevant dependencies to the `xjcPlugins`
-configuration.
-Then set the plugin options through the `options` property.
-
-For example, to use the "Equals" and "Hashcode" plugin from
-the [JAXB2 Basics](https://github.com/highsource/jaxb2-basics) project, configure the following:
-
-```kotlin
-dependencies {
- // For CXF 3 and javax only (does not work with CXF 4 and jakarta):
- implementation("org.jvnet.jaxb2_commons:jaxb2-basics-runtime:1.11.1")
- xjcPlugins("org.jvnet.jaxb2_commons:jaxb2-basics:1.11.1")
-}
-
-wsdl2java {
- options.addAll("-xjc-Xequals", "-xjc-XhashCode")
-}
-```
-
-Note that the example above is for CXF 3 and the older `javax` namespace.
-There is a fork [here](https://github.com/patrodyne/hisrc-basicjaxb) that you may try for CXF 4 and the `jakarta` namespace.
-
-### Enabling the use of the @Generated annotation
-
-CXF (and the underlying XJC tool) can add a `@Generated` annotation to the generated source code.
-This is a source annotation useful for marking classes as generated by a tool.
-It can also be used by some static code analytic tools to skip these classes.
-You can set it by the `markGenerated` configuration:
-
-```kotlin
-wsdl2java {
- markGenerated.set(true)
-}
-```
-
-While very useful in theory, there are some gotchas with this annotation.
-One is that it is a source code annotation and thus won't work with tools that work with byte code (like JaCoCo).
-Another is that here are actually three `@Generated` annotations.
-
-* The first is `javax.annotation.Generated` and is available in the JDK up til and including Java 8. It is also included in the `javax.annotation:javax.annotation-api` dependency.
-* The second is `javax.annotation.processing.Generated` and is available in the JDK from Java 9.
-* the third is `jakarta.annotation.Generated` and is included in the `jakarta.annotation:jakarta.annotation-api` dependency.
-
-XJC 3 uses the first, and XJC 4+ uses the third.
-
-Because your tools may only support a particular version of the `@Generated` annotation, you can select which one through the `generatedStyle` configuration.
-Supported values are: `default`, `jdk8`, `jdk9` and `jakarta`.
-Example:
-
-```kotlin
-dependencies {
- // The dependency below is only needed if using the Java 8 version of @Generated (through "jdk8") on Java 9 or later
- implementation("javax.annotation:javax.annotation-api:1.3.2")
-}
-
-wsdl2java {
- markGenerated.set("jdk8")
-}
-```
-
-The plugin will also, by default, strip any timestamps from the `@Generated` annotations.
-This is to support reproducible builds and the Gradle cache.
-This can be disabled by the `suppressGeneratedDate` configuration:
-
-```kotlin
-wsdl2java {
- suppressGeneratedDate.set(false)
-}
-```
-
-## Other
-
-The plugin will add the following two dependencies to your `implementation` configuration:
-
-```
-jakarta.xml.ws:jakarta.xml.ws-api:2.3.3
-jakarta.jws:jakarta.jws-api:1.1.1
-```
-
-These are required to compile the generated code.
-However, depending on your runtime platform, you may want to exclude them and instead either put them in the `compileOnly` configuration, or use whatever libraries that are
-provided by the platform.
-
-There are full examples available in the integration-test directory.
-
-If you need to compile additional XML schemas (xsd files) not directly referenced by the wsdl files, you can use
-the [com.github.bjornvester.xjc](https://plugins.gradle.org/plugin/com.github.bjornvester.xjc) plugin in addition.
-
-## Limitations
-
-### CXF does not check for unique names in generated resources
-
-The CXF tool will overwrite generated classes from multiple WSDL files if they have the same qualified name.
-Especially the `ObjectFactory` class might be overwritten, which is very annoying.
-
-### CXF is not deterministic
-
-When CXF generates an `ObjectFactory` class, the order of the methods are not deterministic, but depend on the absolute path of the input files.
-This may cause misses in the Gradle build cache, ecp, which may propagate to downstream projects, resulting in long build times.
-I have a local fix for this and I hope to create a PR for it to the relevant Apache project.
-
-## Contributions
-
-I often feel a bit stretched out in terms of maintaining this and my projects.
-For that reason, I might not respond to issues and PRs very often.
+[![Gradle Plugin Release](https://img.shields.io/badge/Gradle%20plugin-1.6.0-blue.svg?logo=data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MCA2Ni4wNiI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNmZmY7fTwvc3R5bGU+PC9kZWZzPjx0aXRsZT5ncmFkbGUtZWxlcGhhbnQtaWNvbi13aGl0ZS1wcmltYXJ5PC90aXRsZT48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik04NS4xMSw0LjE4YTE0LjI3LDE0LjI3LDAsMCwwLTE5LjgzLS4zNCwxLjM4LDEuMzgsMCwwLDAsMCwyTDY3LDcuNmExLjM2LDEuMzYsMCwwLDAsMS43OC4xMkE4LjE4LDguMTgsMCwwLDEsNzkuNSwyMC4wNkM2OC4xNywzMS4zOCw1My4wNS0uMzYsMTguNzMsMTZhNC42NSw0LjY1LDAsMCwwLTIsNi41NGw1Ljg5LDEwLjE3YTQuNjQsNC42NCwwLDAsMCw2LjMsMS43M2wuMTQtLjA4LS4xMS4wOEwzMS41MywzM2E2MC4yOSw2MC4yOSwwLDAsMCw4LjIyLTYuMTMsMS40NCwxLjQ0LDAsMCwxLDEuODctLjA2aDBhMS4zNCwxLjM0LDAsMCwxLC4wNiwyQTYxLjYxLDYxLjYxLDAsMCwxLDMzLDM1LjM0bC0uMDksMC0yLjYxLDEuNDZhNy4zNCw3LjM0LDAsMCwxLTMuNjEuOTQsNy40NSw3LjQ1LDAsMCwxLTYuNDctMy43MWwtNS41Ny05LjYxQzQsMzItMi41NCw0Ni41NiwxLDY1YTEuMzYsMS4zNiwwLDAsMCwxLjMzLDEuMTFIOC42MUExLjM2LDEuMzYsMCwwLDAsMTAsNjQuODdhOS4yOSw5LjI5LDAsMCwxLDE4LjQyLDAsMS4zNSwxLjM1LDAsMCwwLDEuMzQsMS4xOUgzNS45YTEuMzYsMS4zNiwwLDAsMCwxLjM0LTEuMTksOS4yOSw5LjI5LDAsMCwxLDE4LjQyLDBBMS4zNiwxLjM2LDAsMCwwLDU3LDY2LjA2SDYzLjFhMS4zNiwxLjM2LDAsMCwwLDEuMzYtMS4zNGMuMTQtOC42LDIuNDYtMTguNDgsOS4wNy0yMy40M0M5Ni40MywyNC4xNiw5MC40MSw5LjQ4LDg1LjExLDQuMThaTTYxLjc2LDMwLjA1bC00LjM3LTIuMTloMGEyLjc0LDIuNzQsMCwxLDEsNC4zNywyLjJaIi8+PC9zdmc+)](https://plugins.gradle.org/plugin/com.github.bjornvester.xjc)
+[![GitHub Actions status](https://github.com/bjornvester/wsdl2java-gradle-plugin/workflows/CI/badge.svg)](https://github.com/bjornvester/wsdl2java-gradle-plugin/actions)
+
+# wsdl2java-gradle-plugin
+
+A Gradle plugin for generating Java classes from WSDL files through CXF.
+
+## Requirements and main features
+
+* The plugin requires Gradle 7.6 or later. (Tested with Gradle 7 and 8.)
+* For using the Jakarta namespace (default), the plugin requires Java 17 or greater. For the older javax namespace, you can use Java 8, 11 or 17.
+* It supports the Gradle build cache (enabled by setting `org.gradle.caching=true` in your gradle.properties file).
+* It supports the Gradle configuration cache (enabled by setting `org.gradle.configuration-cache=true` in your gradle.properties file").
+* It supports project relocation for the build cache (e.g. you move your project to a new path, or make a new copy/clone of it).
+ This is especially useful in a CI context, where you might clone PRs and/or branches for a repository in their own locations.
+ Note, however, that there is an issue in an Apache library called `org.apache.ws.xmlschema:xmlschema-core` that might break this - see below for details.
+* It supports parallel execution (enabled with `org.gradle.parallel=true` in your gradle.properties file), though it does not itself run anything in parallel.
+
+## Configuration
+
+Apply the plugin ID "com.github.bjornvester.wsdl2java" as specific in the [Gradle Plugin portal page](https://plugins.gradle.org/plugin/com.github.bjornvester.wsdl2java), e.g. like this:
+
+```kotlin
+plugins {
+ id("com.github.bjornvester.wsdl2java") version "2.0.1"
+}
+```
+
+Put your WSDL and referenced XSD files somewhere in your src/main/resource directory.
+By default, the plugin will create Java classes for all the WSDL files in the resource directory.
+
+The generated code will by default end up in the directory build/generated/sources/wsdl2java folder.
+
+You can configure the plugin using the "wsdl2java" extension like this:
+
+```kotlin
+wsdl2java {
+ // Set properties here...
+}
+```
+
+Here is a list of all available properties:
+
+| Property | Type | Default | Description |
+|----------------------------|-----------------------|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| wsdlDir | DirectoryProperty | "$projectDir/src
/main/resources" | The directory holding the WSDL and referenced XSD files to compile. |
+| includes | ListProperty\ | \["**/*.wsdl"] | Inclusion filers (Ant style) for which WSDLs to include. |
+| includesWithOptions | Map\ | \[not set\] | Inclusion filters like above, but with individual options. See below. |
+| generatedSourceDir | DirectoryProperty | "$buildDir/generated
/sources/wsdl2java/java" | The output directory for the generated Java sources.
Note that it will be deleted when running XJC. |
+| bindingFile | RegularFileProperty | \[not set\] | A binding file to use in the schema compiler. |
+| useJakarta | Provider\ | true | Set to use the `jakarta` namespace. If false, uses the `javax` namespace. This value also determines the default version of CXF. |
+| cxfVersion | Provider\ | "4.0.2" for jakarta / 3.5.6 for javax | The version of CXF to use. Use a version >= 4 for `jakarta` and below for `javax`. |
+| verbose | Provider\ | \[not set\] | Enables verbose output from CXF. If not set, it will be be enabled only on the info logging level. |
+| markGenerated | Provider\ | "no" | Adds the @Generated annotation to the generated sources. See below for details as there are some gotchas with this. |
+| generatedStyle | Provider\ | "default" | If using the @Generated annotation, select the type can be overridden by this. See below for details. |
+| suppressGeneratedDate | Provider\ | true | Suppresses generating dates in CXF. Default is true to support reproducible builds and to work with the build cache. |
+| packageName | Provider\ | \[not set\] | Sets the package name for the generated sources |
+| options | ListProperty\ | \[empty\] | Additional options to pass to the tool. See [here](https://cxf.apache.org/docs/wsdl-to-java.html) for details. |
+| addCompilationDependencies | Provider\ | true | Adds dependencies to the `implementation` configuration for compiling the generated sources. These includes `jakarta.xml.ws:jakarta.xml.ws-api`, `jakarta.jws:jakarta.jws-api` and possibly `jakarta.annotation:jakarta.annotation-api`. |
+
+### Configure the CXF version
+
+You can specify the version of CXF used for code generation like this:
+
+```kotlin
+wsdl2java {
+ cxfVersion.set("4.0.2")
+}
+```
+
+### Configure included WSDL files
+
+By default, the plugin will find all WSDL files in the `wsdlDir` directory, which defaults to `src/main/resources`.
+It is important that if you change this, you change it to a folder that contain all resources (e.g. both WSDL and XSDs).
+Otherwise, if you make changes to files outside this folder, Gradle will not see them and thus might consider the task
+up-to-date.
+
+The plugin will set the `wsdlLocation` property of the `@WebServiceClient` to the path for the WSDL file relative to
+the `wsdlDir` directory.
+If you change `wsdlDir` in a way where this no longer makes sense, you need to set the option yourself.
+If you have multiple WSDL files, see the section on additional options.
+
+If you have multiple WSDL files and want to only run the tool on some of them, you can use the `includes` property.
+Example:
+
+```kotlin
+// Only if different from the default 'src/main/resources'
+wsdlDir.set(layout.projectDirectory.dir("src/main/wsdl"))
+
+// For Kotlin DSL
+includes.set(
+ listOf(
+ "src/main/wsdls/MyFirstService.wsdl",
+ "src/main/wsdls/MySecondService.wsdl"
+ )
+)
+```
+
+```groovy
+// For Groovy DSL
+includes = [
+ "src/main/wsdls/MyFirstService.wsdl",
+ "src/main/wsdls/MySecondService.wsdl"
+]
+```
+
+### Configure additional options
+
+Besides the options given in the `wsdl2java` extension, you can provide additional options directly to CXF (and XJC)
+through the `options` property:
+
+```kotlin
+// For Kotlin DSL
+includes.set(
+ listOf(
+ "xjc-no-header",
+ "xjc-npa"
+ )
+)
+
+// For Groovy DSL
+includes = [
+ "xjc-no-header",
+ "xjc-npa"
+]
+```
+
+See [here](https://cxf.apache.org/docs/wsdl-to-java.html) for the available options.
+
+#### Configure additional options for individual WSDL files
+
+It is possible to pass options for individual WSDL files.
+This is important especially if you need to explicitly configure the `wsdlLocation` option, as it doesn't make to have
+the same location in all files.
+(But note that if you leave it out, the plugin will guess it based on the file location.)
+
+```kotlin
+// For Kotlin DSL
+includesWithOptions.set(
+ mapOf(
+ "**/ServiceA.wsdl" to listOf("-wsdlLocation", "https://example.com/service-a?wsdl"),
+ "**/ServiceB.wsdl" to listOf("-wsdlLocation", "https://example.com/service-b?wsdl")
+ )
+)
+```
+
+```groovy
+// For Groovy DSL
+includes = [
+ "**/ServiceA.wsdl": ["-wsdlLocation", "https://example.com/service-a?wsdl"],
+ "**/ServiceB.wsdl": ["-wsdlLocation", "https://example.com/service-b?wsdl"]
+]
+```
+
+### Configure the output directory
+
+You can optionally specify the directory for the generated source through the `generatedSourceDir` property, which
+defaults to `$buildDir/generated/sources/wsdl2java/java`.
+Example:
+
+```kotlin
+wsdl2java {
+ generatedSourceDir.set(layout.projectDirectory.dir("src/generated/wsdl2java"))
+}
+```
+
+Note that the directory will be wiped completely on each run, so don't put other source files in it.
+
+### Configure binding files
+
+A binding file can be added like this:
+
+```kotlin
+wsdl2java {
+ bindingFile.set(layout.projectDirectory.file("src/main/bindings/binding.xjb"))
+}
+```
+
+If you get a warning on maximum enum member size, you can raise the maximum like this:
+
+```xml
+
+
+
+
+
+
+
+
+
+```
+
+If you are using the older `javax` namespace instead of `jakarta`, set the `jxb` attribute to `http://java.sun.com/xml/ns/jaxb` instead and the version to 2.1.
+
+If you like to use the Java Date/Time API instead of the more clunky GregorianCalendar class, you can
+use [threeten-jaxb](https://github.com/threeten-jaxb/threeten-jaxb) library with a binding file like example below.
+
+```kotlin
+dependencies {
+ implementation("io.github.threeten-jaxb:threeten-jaxb-core:2.1.0")
+}
+
+wsdl2java {
+ bindingFile.set(layout.projectDirectory.file("src/main/bindings/bindings.xjb"))
+}
+```
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+```
+
+In the above, for `javax`, use version 1.2.0 and the binding attributes to `xmlns="http://java.sun.com/xml/ns/jaxb" version="2.1"`.
+
+Note that at the moment, it is not possible to specify more than one binding file in the extension. If you require this,
+use the `-b` option.
+
+### Configuring package names
+
+The package name for the generated resources can be configured with the `packageName` field:
+
+```kotlin
+wsdl2java {
+ packageName.set("com.github.bjornvester.wsdl2java.group1")
+}
+
+```
+
+### Configure encoding
+
+If your WSDL files include non-ANSI characters, you should set the corresponding file encoding in your gradle.properties
+file. E.g.:
+
+```properties
+org.gradle.jvmargs=-Dfile.encoding=UTF-8
+```
+
+If you are on a POSIX operating system (e.g. Linux), you may in addition to this need to set your operating system
+locale to one that supports your encoding.
+Otherwise, Java (and therefore also Gradle and CXF) may not be able to create files with names outside of what your
+default locale supports.
+Especially some Docker images, like the Java ECR images from AWS, are by default set to a locale supporting ASCII only.
+If this is the case for you, and you want to use UTF-8, you could export an environment variable like this:
+
+```shell script
+export LANG=C.UTF-8
+```
+
+### Using javax instead of the jakarta namespace
+
+To use the older javax namespace in the generated files, set the `useJakarta` property to `false.
+
+```kotlin
+wsdl2java {
+ useJakarta.set(false)
+}
+```
+
+### Activating (third party) XJC plugins
+
+To use third party plugins for the underlying XJC tool, supply the relevant dependencies to the `xjcPlugins`
+configuration.
+Then set the plugin options through the `options` property.
+
+For example, to use the "Equals" and "Hashcode" plugin from
+the [JAXB2 Basics](https://github.com/highsource/jaxb2-basics) project, configure the following:
+
+```kotlin
+dependencies {
+ // For CXF 3 and javax only (does not work with CXF 4 and jakarta):
+ implementation("org.jvnet.jaxb2_commons:jaxb2-basics-runtime:0.13.1")
+ xjcPlugins("org.jvnet.jaxb2_commons:jaxb2-basics:0.13.1")
+}
+
+wsdl2java {
+ options.addAll("-xjc-Xequals", "-xjc-XhashCode")
+}
+```
+
+Note that the example above is for CXF 3 and the older `javax` namespace.
+There is a fork [here](https://github.com/patrodyne/hisrc-basicjaxb) that you may try for CXF 4 and the `jakarta` namespace.
+
+### Enabling the use of the @Generated annotation
+
+CXF (and the underlying XJC tool) can add a `@Generated` annotation to the generated source code.
+This is a source annotation useful for marking classes as generated by a tool.
+It can also be used by some static code analytic tools to skip these classes.
+You can set it by the `markGenerated` configuration:
+
+```kotlin
+wsdl2java {
+ markGenerated.set(true)
+}
+```
+
+While very useful in theory, there are some gotchas with this annotation.
+One is that it is a source code annotation and thus won't work with tools that work with byte code (like JaCoCo).
+Another is that here are actually three `@Generated` annotations.
+
+* The first is `javax.annotation.Generated` and is available in the JDK up til and including Java 8. It is also included in the `javax.annotation:javax.annotation-api` dependency.
+* The second is `javax.annotation.processing.Generated` and is available in the JDK from Java 9.
+* the third is `jakarta.annotation.Generated` and is included in the `jakarta.annotation:jakarta.annotation-api` dependency.
+
+XJC 3 uses the first, and XJC 4+ uses the third.
+
+Because your tools may only support a particular version of the `@Generated` annotation, you can select which one through the `generatedStyle` configuration.
+Supported values are: `default`, `jdk8`, `jdk9` and `jakarta`.
+Example:
+
+```kotlin
+dependencies {
+ // The dependency below is only needed if using the Java 8 version of @Generated (through "jdk8") on Java 9 or later
+ implementation("javax.annotation:javax.annotation-api:1.3.2")
+}
+
+wsdl2java {
+ markGenerated.set("jdk8")
+}
+```
+
+The plugin will also, by default, strip any timestamps from the `@Generated` annotations.
+This is to support reproducible builds and the Gradle cache.
+This can be disabled by the `suppressGeneratedDate` configuration:
+
+```kotlin
+wsdl2java {
+ suppressGeneratedDate.set(false)
+}
+```
+
+## Groups
+If the `includesWithOptions` is not enough, you can also make groups of WSDL files, each having their own extension.
+This is done like this:
+
+```kotlin
+wsdl2java {
+ groups {
+ register("group1") {
+ includes.set(listOf("**/HelloWorldAService.wsdl"))
+ options.set(listOf("-wsdlLocation", "MyLocationA"))
+ packageName.set("com.github.bjornvester.wsdl2java.group1")
+ }
+ register("group2") {
+ includes.set(listOf("**/HelloWorldBService.wsdl"))
+ options.set(listOf("-wsdlLocation", "MyLocationB"))
+ packageName.set("com.github.bjornvester.wsdl2java.group2")
+ }
+ }
+}
+```
+
+In order to avoid generating resources with the same name but different content (for instance like the generated `ObjectFactory` class), you should make sure each group use its own package name.
+
+## Other
+
+The plugin will add the following two dependencies to your `implementation` configuration:
+
+```
+jakarta.xml.ws:jakarta.xml.ws-api:2.3.3
+jakarta.jws:jakarta.jws-api:1.1.1
+```
+
+These are required to compile the generated code.
+However, depending on your runtime platform, you may want to exclude them and instead either put them in the `compileOnly` configuration, or use whatever libraries that are
+provided by the platform.
+
+There are full examples available in the integration-test directory.
+
+If you need to compile additional XML schemas (xsd files) not directly referenced by the wsdl files, you can use
+the [com.github.bjornvester.xjc](https://plugins.gradle.org/plugin/com.github.bjornvester.xjc) plugin in addition.
+
+## Limitations
+
+### CXF does not check for unique names in generated resources
+
+The CXF tool will overwrite generated classes from multiple WSDL files if they have the same qualified name.
+Especially the `ObjectFactory` class might be overwritten, which is very annoying.
+
+### CXF is not deterministic
+
+When CXF generates an `ObjectFactory` class, the order of the methods are not deterministic, but depend on the absolute path of the input files.
+This may cause misses in the Gradle build cache, ecp, which may propagate to downstream projects, resulting in long build times.
+I have a local fix for this and I hope to create a PR for it to the relevant Apache project.
+
+## Contributions
+
+I often feel a bit stretched out in terms of maintaining this and my other projects.
+For that reason, I might not respond to issues and PRs very often.
diff --git a/build.gradle.kts b/build.gradle.kts
index be30ddd..4f1c8ca 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,65 +1,60 @@
-plugins {
- `kotlin-dsl`
- id("java-gradle-plugin")
- id("com.gradle.plugin-publish") version "1.2.0"
-}
-
-group = "com.github.bjornvester"
-version = "2.0"
-
-repositories {
- mavenCentral()
-}
-
-java {
- toolchain {
- languageVersion.set(JavaLanguageVersion.of(8))
- }
-}
-
-// The integration test folder is an input to the unit test in the root project
-// Register these files as inputs
-tasks.withType().configureEach {
- inputs
- .files(layout.projectDirectory.dir("integration-test").asFileTree.matching {
- exclude("**/build/**")
- exclude("**/gradle/**")
- })
- .withPathSensitivity(PathSensitivity.RELATIVE)
- useJUnitPlatform()
- systemProperty("GRADLE_ROOT_FOLDER", projectDir.absolutePath)
- systemProperty("GRADLE_PLUGIN_VERSION", version)
-}
-
-tasks.withType {
- gradleVersion = "latest"
-}
-
-dependencies {
- compileOnly("org.apache.cxf:cxf-tools-wsdlto-core:4.0.2")
- testImplementation("commons-io:commons-io:2.13.0")
- testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3")
- testImplementation("org.junit.jupiter:junit-jupiter-params")
- testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
-}
-
-gradlePlugin {
- website.set("https://github.com/bjornvester/wsdl2java-gradle-plugin")
- vcsUrl.set("https://github.com/bjornvester/wsdl2java-gradle-plugin")
- plugins {
- create("wsdl2JavaPlugin") {
- id = "com.github.bjornvester.wsdl2java"
- description = """Adds the CXF wsdl2java tool to your project.
- |Please see the Github project page for details.""".trimMargin()
- displayName = "Gradle Wsdl2Java plugin"
- tags.set(listOf("wsdl2java", "cxf", "wsimport"))
- implementationClass = "com.github.bjornvester.wsdl2java.Wsdl2JavaPlugin"
- description = "Changes:\n" +
- " - Added support for using the jakarta namespace, which is now the default. The older javax namespace can be enabled with a configuration change.\n" +
- " - Added support for the Gradle configuration cache.\n" +
- " - The Wsdl2Java task now runs with the configured, or default, Java Toolchain.\n" +
- " - Minimum required of version of Gradle is now 6.7 (up from 6.0).\n" +
- " - The configurations for marking generated code has changed to support a third variant of the Generated annotation. See the README for details."
- }
- }
-}
+plugins {
+ `kotlin-dsl`
+ id("java-gradle-plugin")
+ id("com.gradle.plugin-publish") version "1.2.0"
+}
+
+group = "com.github.bjornvester"
+version = "2.0.1"
+
+repositories {
+ mavenCentral()
+}
+
+java {
+ toolchain {
+ languageVersion.set(JavaLanguageVersion.of(8))
+ }
+}
+
+// The integration test folder is an input to the unit test in the root project
+// Register these files as inputs
+tasks.withType().configureEach {
+ inputs
+ .files(layout.projectDirectory.dir("integration-test").asFileTree.matching {
+ exclude("**/build/**")
+ exclude("**/gradle/**")
+ })
+ .withPathSensitivity(PathSensitivity.RELATIVE)
+ useJUnitPlatform()
+ systemProperty("GRADLE_ROOT_FOLDER", projectDir.absolutePath)
+ systemProperty("GRADLE_PLUGIN_VERSION", version)
+}
+
+tasks.withType {
+ gradleVersion = "latest"
+}
+
+dependencies {
+ compileOnly("org.apache.cxf:cxf-tools-wsdlto-core:4.0.2")
+ testImplementation("commons-io:commons-io:2.13.0")
+ testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3")
+ testImplementation("org.junit.jupiter:junit-jupiter-params")
+ testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
+}
+
+gradlePlugin {
+ website.set("https://github.com/bjornvester/wsdl2java-gradle-plugin")
+ vcsUrl.set("https://github.com/bjornvester/wsdl2java-gradle-plugin")
+ plugins {
+ create("wsdl2JavaPlugin") {
+ id = "com.github.bjornvester.wsdl2java"
+ displayName = "Gradle Wsdl2Java plugin"
+ tags.set(listOf("wsdl2java", "cxf", "wsimport"))
+ implementationClass = "com.github.bjornvester.wsdl2java.Wsdl2JavaPlugin"
+ description = "Changes:\n" +
+ " - Fixed a problem in older versions of Gradle when not specifying a Java toolchain.\n" +
+ " - Due to compatability issues not found version 2.0.0 of the plugin, the plugin now requires at least Gradle 7.6"
+ }
+ }
+}
diff --git a/integration-test/buildSrc/src/main/kotlin/com.github.bjornvester.wsdl2java.internal.java-conventions-cxf3.gradle.kts b/integration-test/buildSrc/src/main/kotlin/com.github.bjornvester.wsdl2java.internal.java-conventions-cxf3.gradle.kts
index 4c01823..206fe10 100644
--- a/integration-test/buildSrc/src/main/kotlin/com.github.bjornvester.wsdl2java.internal.java-conventions-cxf3.gradle.kts
+++ b/integration-test/buildSrc/src/main/kotlin/com.github.bjornvester.wsdl2java.internal.java-conventions-cxf3.gradle.kts
@@ -13,8 +13,6 @@ dependencies {
java {
toolchain {
- // Note that the unit test in the root project modifies the line below
- // Be careful making changes
languageVersion.set(JavaLanguageVersion.of(8))
}
}
diff --git a/integration-test/buildSrc/src/main/kotlin/com.github.bjornvester.wsdl2java.internal.java-conventions-cxf4.gradle.kts b/integration-test/buildSrc/src/main/kotlin/com.github.bjornvester.wsdl2java.internal.java-conventions-cxf4.gradle.kts
index 2d2b99b..f5ef569 100644
--- a/integration-test/buildSrc/src/main/kotlin/com.github.bjornvester.wsdl2java.internal.java-conventions-cxf4.gradle.kts
+++ b/integration-test/buildSrc/src/main/kotlin/com.github.bjornvester.wsdl2java.internal.java-conventions-cxf4.gradle.kts
@@ -14,8 +14,6 @@ dependencies {
java {
toolchain {
- // Note that the unit test in the root project modifies the line below
- // Be careful making changes
languageVersion.set(JavaLanguageVersion.of(17))
}
}
\ No newline at end of file
diff --git a/integration-test/cxf3/bindings-datetime-test/src/main/bindings/bindings.xml b/integration-test/cxf3/bindings-datetime-test/src/main/bindings/bindings.xml
index 5471c8e..b0ee119 100644
--- a/integration-test/cxf3/bindings-datetime-test/src/main/bindings/bindings.xml
+++ b/integration-test/cxf3/bindings-datetime-test/src/main/bindings/bindings.xml
@@ -1,5 +1,6 @@
+ xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
+ extensionBindingPrefixes="xjc">
diff --git a/integration-test/cxf4/bindings-datetime-test-jakarta/src/main/bindings/bindings.xml b/integration-test/cxf4/bindings-datetime-test-jakarta/src/main/bindings/bindings.xml
index 1e143dd..00fd265 100644
--- a/integration-test/cxf4/bindings-datetime-test-jakarta/src/main/bindings/bindings.xml
+++ b/integration-test/cxf4/bindings-datetime-test-jakarta/src/main/bindings/bindings.xml
@@ -1,5 +1,6 @@
+ xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
+ extensionBindingPrefixes="xjc">
diff --git a/integration-test/settings.gradle.kts b/integration-test/settings.gradle.kts
index d6ec7d1..367005d 100644
--- a/integration-test/settings.gradle.kts
+++ b/integration-test/settings.gradle.kts
@@ -1,21 +1,19 @@
-plugins {
- id("org.gradle.toolchains.foojay-resolver-convention") version ("0.5.0")
-}
-
-includeBuild("..")
-
-include(
- // Note that the lines below are modified by the unit test in the root project.
- // Be careful making changes.
- "cxf4:bindings-datetime-test-jakarta",
- "cxf4:filter-test",
- "cxf4:grouping-test",
- "cxf4:includes-options-test",
- "cxf4:utf8-test",
-
- "cxf3:bindings-datetime-test",
- "cxf3:generated-annotation-test",
- "cxf3:xjc-plugins-test"
-)
-
-//enableFeaturePreview("STABLE_CONFIGURATION_CACHE")
+plugins {
+ id("org.gradle.toolchains.foojay-resolver-convention") version ("0.5.0")
+}
+
+includeBuild("..")
+
+include(
+ // Note that the lines below are modified by the unit test in the root project.
+ // Be careful making changes.
+ "cxf4:bindings-datetime-test-jakarta",
+ "cxf4:filter-test",
+ "cxf4:grouping-test",
+ "cxf4:includes-options-test",
+ "cxf4:utf8-test",
+
+ "cxf3:bindings-datetime-test",
+ "cxf3:generated-annotation-test",
+ "cxf3:xjc-plugins-test"
+)
diff --git a/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaPlugin.kt b/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaPlugin.kt
index 9ce115b..8e17f68 100644
--- a/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaPlugin.kt
+++ b/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaPlugin.kt
@@ -1,125 +1,120 @@
-package com.github.bjornvester.wsdl2java
-
-import com.github.bjornvester.wsdl2java.Wsdl2JavaPluginExtension.Companion.GENERATED_STYLE_JDK9
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import org.gradle.api.artifacts.Configuration
-import org.gradle.api.artifacts.Dependency
-import org.gradle.api.plugins.JavaPlugin
-import org.gradle.api.plugins.JavaPluginExtension
-import org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME
-import org.gradle.api.tasks.SourceSetContainer
-import org.gradle.api.tasks.TaskProvider
-import org.gradle.jvm.toolchain.JavaToolchainService
-import org.gradle.util.GradleVersion
-
-class Wsdl2JavaPlugin : Plugin {
- companion object {
- const val MINIMUM_GRADLE_VERSION = "6.7"
- const val MINIMUM_GRADLE_VERSION_GROUPING = "7.0"
- const val PLUGIN_ID = "com.github.bjornvester.wsdl2java"
- const val WSDL2JAVA_TASK_NAME = "wsdl2java"
- const val WSDL2JAVA_EXTENSION_NAME = "wsdl2java"
- const val WSDL2JAVA_CONFIGURATION_NAME = "wsdl2java"
- const val XJC_PLUGINS_CONFIGURATION_NAME = "xjcPlugins"
- }
-
- override fun apply(project: Project) {
- project.logger.info("Applying $PLUGIN_ID to project ${project.name}")
- verifyGradleVersion()
- project.plugins.apply(JavaPlugin::class.java)
- val extension = project.extensions.create(WSDL2JAVA_EXTENSION_NAME, Wsdl2JavaPluginExtension::class.java)
- val wsdl2JavaConfiguration = createResolvableConfiguration(project, WSDL2JAVA_CONFIGURATION_NAME)
- createResolvableConfiguration(project, XJC_PLUGINS_CONFIGURATION_NAME)
-
- wsdl2JavaConfiguration.defaultDependencies {
- addLater(extension.cxfVersion.map { project.dependencies.create("org.apache.cxf:cxf-tools-wsdlto-frontend-jaxws:$it") })
- addLater(extension.cxfVersion.map { project.dependencies.create("org.apache.cxf:cxf-tools-wsdlto-databinding-jaxb:$it") })
- addLater(extension.useJakarta.map { if (it) "3.0.1" else "2.3.3" }.map { project.dependencies.create("jakarta.xml.ws:jakarta.xml.ws-api:$it") })
- addLater(extension.useJakarta.map { if (it) "2.1.1" else "1.3.5" }.map { project.dependencies.create("jakarta.annotation:jakarta.annotation-api:$it") })
- add(project.dependencies.create("org.slf4j:slf4j-simple:1.7.36"))
- }
-
- project.configurations.named("implementation") {
- // The listProperty thing is a work-around for https://github.com/gradle/gradle/issues/13255
- dependencies.addAllLater(project.objects.listProperty(Dependency::class.java).convention(extension.addCompilationDependencies.map {
- val deps = listOf().toMutableList();
- if (it) {
- val wsApiVersion = if (extension.useJakarta.get()) "3.0.1" else "2.3.3"
- val jwsApiVersion = if (extension.useJakarta.get()) "3.0.0" else "1.1.1"
- deps.add(project.dependencies.create("jakarta.xml.ws:jakarta.xml.ws-api:$wsApiVersion"))
- deps.add(project.dependencies.create("jakarta.jws:jakarta.jws-api:$jwsApiVersion"))
- if (extension.markGenerated.get() && extension.generatedStyle.get() != GENERATED_STYLE_JDK9) {
- val annotationsApiVersion = if (extension.useJakarta.get()) "2.1.1" else "1.3.5"
- deps.add(project.dependencies.create("jakarta.annotation:jakarta.annotation-api:$annotationsApiVersion"))
- }
- }
- deps
- }))
- }
-
- val defaultTask = addWsdl2JavaTask(WSDL2JAVA_TASK_NAME, project, extension)
-
- extension.groups.all {
- if (GradleVersion.current() < GradleVersion.version(MINIMUM_GRADLE_VERSION_GROUPING)) {
- throw UnsupportedOperationException("Plugin $PLUGIN_ID requires at least Gradle $MINIMUM_GRADLE_VERSION_GROUPING when using the 'groups' property, but you are using ${GradleVersion.current().version}")
- }
-
- defaultTask.configure {
- enabled = false
- }
-
- addWsdl2JavaTask(WSDL2JAVA_TASK_NAME + name.replaceFirstChar(Char::titlecase), project, this)
- }
- }
-
- private fun addWsdl2JavaTask(name: String, project: Project, group: Wsdl2JavaPluginExtensionGroup): TaskProvider {
- val wsdl2JavaTask = project.tasks.register(name, Wsdl2JavaTask::class.java) {
- wsdlInputDir.convention(group.wsdlDir)
- includes.convention(group.includes)
- includesWithOptions.convention(group.includesWithOptions)
- bindingFile.convention(group.bindingFile)
- options.convention(group.options)
- verbose.convention(group.verbose)
- suppressGeneratedDate.convention(group.suppressGeneratedDate)
- markGenerated.convention(group.markGenerated)
- sourcesOutputDir.convention(group.generatedSourceDir)
- packageName.convention(group.packageName)
- wsdl2JavaConfiguration.from(project.configurations.named(WSDL2JAVA_CONFIGURATION_NAME))
- xjcPluginsConfiguration.from(project.configurations.named(XJC_PLUGINS_CONFIGURATION_NAME))
-
- val toolchainService = project.extensions.getByType(JavaToolchainService::class.java)
- val currentJavaToolchain = project.extensions.getByType(JavaPluginExtension::class.java).toolchain
- val currentJvmLauncherProvider = toolchainService.launcherFor(currentJavaToolchain)
- javaLauncher.convention(currentJvmLauncherProvider)
-
- val sourceSets = project.properties["sourceSets"] as SourceSetContainer
- sourceSets.named(MAIN_SOURCE_SET_NAME) {
- java.srcDir(sourcesOutputDir)
- }
- }
-
- project.tasks.named(JavaPlugin.COMPILE_JAVA_TASK_NAME) {
- dependsOn(wsdl2JavaTask)
- }
-
- return wsdl2JavaTask
- }
-
- private fun verifyGradleVersion() {
- if (GradleVersion.current() < GradleVersion.version(MINIMUM_GRADLE_VERSION)) {
- throw UnsupportedOperationException(
- "Plugin $PLUGIN_ID requires at least Gradle $MINIMUM_GRADLE_VERSION, " +
- "but you are using ${GradleVersion.current().version}"
- )
- }
- }
-
- private fun createResolvableConfiguration(project: Project, name: String): Configuration {
- return project.configurations.maybeCreate(name).apply {
- isCanBeConsumed = false
- isCanBeResolved = true
- isVisible = false
- }
- }
-}
+package com.github.bjornvester.wsdl2java
+
+import com.github.bjornvester.wsdl2java.Wsdl2JavaPluginExtension.Companion.GENERATED_STYLE_JDK9
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.artifacts.Dependency
+import org.gradle.api.plugins.JavaPlugin
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME
+import org.gradle.api.tasks.SourceSetContainer
+import org.gradle.api.tasks.TaskProvider
+import org.gradle.jvm.toolchain.JavaToolchainService
+import org.gradle.util.GradleVersion
+
+class Wsdl2JavaPlugin : Plugin {
+ companion object {
+ const val MINIMUM_GRADLE_VERSION = "7.6"
+ const val PLUGIN_ID = "com.github.bjornvester.wsdl2java"
+ const val WSDL2JAVA_TASK_NAME = "wsdl2java"
+ const val WSDL2JAVA_EXTENSION_NAME = "wsdl2java"
+ const val WSDL2JAVA_CONFIGURATION_NAME = "wsdl2java"
+ const val XJC_PLUGINS_CONFIGURATION_NAME = "xjcPlugins"
+ }
+
+ override fun apply(project: Project) {
+ project.logger.info("Applying $PLUGIN_ID to project ${project.name}")
+ verifyGradleVersion()
+ project.plugins.apply(JavaPlugin::class.java)
+ val extension = project.extensions.create(WSDL2JAVA_EXTENSION_NAME, Wsdl2JavaPluginExtension::class.java)
+ val wsdl2JavaConfiguration = createResolvableConfiguration(project, WSDL2JAVA_CONFIGURATION_NAME)
+ createResolvableConfiguration(project, XJC_PLUGINS_CONFIGURATION_NAME)
+
+ wsdl2JavaConfiguration.defaultDependencies {
+ addLater(extension.cxfVersion.map { project.dependencies.create("org.apache.cxf:cxf-tools-wsdlto-frontend-jaxws:$it") })
+ addLater(extension.cxfVersion.map { project.dependencies.create("org.apache.cxf:cxf-tools-wsdlto-databinding-jaxb:$it") })
+ addLater(extension.useJakarta.map { if (it) "3.0.1" else "2.3.3" }.map { project.dependencies.create("jakarta.xml.ws:jakarta.xml.ws-api:$it") })
+ addLater(extension.useJakarta.map { if (it) "2.1.1" else "1.3.5" }.map { project.dependencies.create("jakarta.annotation:jakarta.annotation-api:$it") })
+ add(project.dependencies.create("org.slf4j:slf4j-simple:1.7.36"))
+ }
+
+ project.configurations.named(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) {
+ // The listProperty thing is a work-around for https://github.com/gradle/gradle/issues/13255
+ dependencies.addAllLater(project.objects.listProperty(Dependency::class.java).convention(extension.addCompilationDependencies.map {
+ val deps = listOf().toMutableList()
+ if (it) {
+ val wsApiVersion = if (extension.useJakarta.get()) "3.0.1" else "2.3.3"
+ val jwsApiVersion = if (extension.useJakarta.get()) "3.0.0" else "1.1.1"
+ deps.add(project.dependencies.create("jakarta.xml.ws:jakarta.xml.ws-api:$wsApiVersion"))
+ deps.add(project.dependencies.create("jakarta.jws:jakarta.jws-api:$jwsApiVersion"))
+ if (extension.markGenerated.get() && extension.generatedStyle.get() != GENERATED_STYLE_JDK9) {
+ val annotationsApiVersion = if (extension.useJakarta.get()) "2.1.1" else "1.3.5"
+ deps.add(project.dependencies.create("jakarta.annotation:jakarta.annotation-api:$annotationsApiVersion"))
+ }
+ }
+ deps
+ }))
+ }
+
+ val defaultTask = addWsdl2JavaTask(WSDL2JAVA_TASK_NAME, project, extension)
+
+ extension.groups.all {
+ defaultTask.configure {
+ enabled = false
+ }
+
+ addWsdl2JavaTask(WSDL2JAVA_TASK_NAME + name.replaceFirstChar(Char::titlecase), project, this)
+ }
+ }
+
+ private fun addWsdl2JavaTask(name: String, project: Project, group: Wsdl2JavaPluginExtensionGroup): TaskProvider {
+ val wsdl2JavaTask = project.tasks.register(name, Wsdl2JavaTask::class.java) {
+ wsdlInputDir.convention(group.wsdlDir)
+ includes.convention(group.includes)
+ includesWithOptions.convention(group.includesWithOptions)
+ bindingFile.convention(group.bindingFile)
+ options.convention(group.options)
+ verbose.convention(group.verbose)
+ suppressGeneratedDate.convention(group.suppressGeneratedDate)
+ markGenerated.convention(group.markGenerated)
+ sourcesOutputDir.convention(group.generatedSourceDir)
+ packageName.convention(group.packageName)
+ wsdl2JavaConfiguration.from(project.configurations.named(WSDL2JAVA_CONFIGURATION_NAME))
+ xjcPluginsConfiguration.from(project.configurations.named(XJC_PLUGINS_CONFIGURATION_NAME))
+
+ val toolchainService = project.extensions.getByType(JavaToolchainService::class.java)
+ val currentJavaToolchain = project.extensions.getByType(JavaPluginExtension::class.java).toolchain
+ val currentJvmLauncherProvider = toolchainService.launcherFor(currentJavaToolchain)
+ javaLauncher.convention(currentJvmLauncherProvider)
+
+ val sourceSets = project.properties["sourceSets"] as SourceSetContainer
+ sourceSets.named(MAIN_SOURCE_SET_NAME) {
+ java.srcDir(sourcesOutputDir)
+ }
+ }
+
+ project.tasks.named(JavaPlugin.COMPILE_JAVA_TASK_NAME) {
+ dependsOn(wsdl2JavaTask)
+ }
+
+ return wsdl2JavaTask
+ }
+
+ private fun verifyGradleVersion() {
+ if (GradleVersion.current() < GradleVersion.version(MINIMUM_GRADLE_VERSION)) {
+ throw UnsupportedOperationException(
+ "Plugin $PLUGIN_ID requires at least Gradle $MINIMUM_GRADLE_VERSION, " +
+ "but you are using ${GradleVersion.current().version}"
+ )
+ }
+ }
+
+ private fun createResolvableConfiguration(project: Project, name: String): Configuration {
+ return project.configurations.maybeCreate(name).apply {
+ isCanBeConsumed = false
+ isCanBeResolved = true
+ isVisible = false
+ }
+ }
+}
diff --git a/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaPluginExtension.kt b/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaPluginExtension.kt
index 482a8d4..d7e4e95 100644
--- a/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaPluginExtension.kt
+++ b/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaPluginExtension.kt
@@ -7,8 +7,8 @@ import org.gradle.api.provider.Property
import javax.inject.Inject
open class Wsdl2JavaPluginExtension @Inject constructor(objects: ObjectFactory, layout: ProjectLayout) : Wsdl2JavaPluginExtensionGroup {
- val useJakarta: Property = objects.property(Boolean::class.java).convention(true)
- val cxfVersion: Property = objects.property(String::class.java).convention(useJakarta.map { if (it) "4.0.2" else "3.5.6" })
+ val useJakarta = objects.property(Boolean::class.java).convention(true)
+ val cxfVersion = objects.property(String::class.java).convention(useJakarta.map { if (it) "4.0.2" else "3.5.6" })
val addCompilationDependencies: Property = objects.property(Boolean::class.java).convention(true)
override val name = "Defaults"
diff --git a/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaTask.kt b/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaTask.kt
index bfd4eb9..0dcda0e 100644
--- a/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaTask.kt
+++ b/src/main/kotlin/com/github/bjornvester/wsdl2java/Wsdl2JavaTask.kt
@@ -20,9 +20,9 @@ import javax.inject.Inject
@CacheableTask
abstract class Wsdl2JavaTask @Inject constructor(
- private val workerExecutor: WorkerExecutor,
- private val fileOperations: FileOperations,
- objects: ObjectFactory
+ private val workerExecutor: WorkerExecutor,
+ private val fileOperations: FileOperations,
+ objects: ObjectFactory
) : DefaultTask() {
@get:InputDirectory
@get:PathSensitive(PathSensitivity.RELATIVE)
@@ -71,6 +71,7 @@ abstract class Wsdl2JavaTask @Inject constructor(
@get:OutputDirectory
val sourcesOutputDir: DirectoryProperty = objects.directoryProperty().convention(getWsdl2JavaExtension().generatedSourceDir)
+ @Optional
@get:Nested
val javaLauncher: Property = objects.property(JavaLauncher::class.java)
@@ -87,7 +88,9 @@ abstract class Wsdl2JavaTask @Inject constructor(
fileOperations.mkdir(sourcesOutputDir)
val workerExecutor = workerExecutor.processIsolation {
- forkOptions.executable = javaLauncher.get().executablePath.asFile.absolutePath;
+ if (javaLauncher.isPresent) {
+ forkOptions.executable = javaLauncher.get().executablePath.asFile.absolutePath
+ }
/*
All gradle worker processes have Xerces2 on the classpath.
@@ -98,10 +101,10 @@ abstract class Wsdl2JavaTask @Inject constructor(
The JDK comes with an internal implementation of a SAXParser, also based on Xerces, but supports the properties to control external file access.
*/
forkOptions.systemProperties = mapOf(
- "javax.xml.parsers.DocumentBuilderFactory" to "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl",
- "javax.xml.parsers.SAXParserFactory" to "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl",
- "javax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema" to "org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory",
- "javax.xml.accessExternalSchema" to "all"
+ "javax.xml.parsers.DocumentBuilderFactory" to "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl",
+ "javax.xml.parsers.SAXParserFactory" to "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl",
+ "javax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema" to "org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory",
+ "javax.xml.accessExternalSchema" to "all"
)
if (logger.isDebugEnabled) {
@@ -114,8 +117,8 @@ abstract class Wsdl2JavaTask @Inject constructor(
forkOptions.environment("LANG", System.getenv("LANG") ?: "C.UTF-8")
classpath
- .from(wsdl2JavaConfiguration)
- .from(xjcPluginsConfiguration)
+ .from(wsdl2JavaConfiguration)
+ .from(xjcPluginsConfiguration)
}
val defaultArgs = buildDefaultArguments()
@@ -140,37 +143,37 @@ abstract class Wsdl2JavaTask @Inject constructor(
}
private fun addWsdlToArgs(
- includePattern: List?,
- defaultArgs: List,
- wsdlToArgs: MutableMap>
+ includePattern: List?,
+ defaultArgs: List,
+ wsdlToArgs: MutableMap>
) {
wsdlInputDir
- .asFileTree
- .matching { if (includePattern != null) include(includePattern) }
- .forEach { wsdlFile ->
- val computedArgs = mutableListOf()
- computedArgs.addAll(defaultArgs)
-
- if (!computedArgs.contains("-wsdlLocation")) {
- computedArgs.addAll(
- listOf(
- "-wsdlLocation",
- wsdlFile.relativeTo(wsdlInputDir.asFile.get()).invariantSeparatorsPath
- )
+ .asFileTree
+ .matching { if (includePattern != null) include(includePattern) }
+ .forEach { wsdlFile ->
+ val computedArgs = mutableListOf()
+ computedArgs.addAll(defaultArgs)
+
+ if (!computedArgs.contains("-wsdlLocation")) {
+ computedArgs.addAll(
+ listOf(
+ "-wsdlLocation",
+ wsdlFile.relativeTo(wsdlInputDir.asFile.get()).invariantSeparatorsPath
)
- }
-
- computedArgs.add(wsdlFile.path)
- wsdlToArgs[wsdlFile.path] = computedArgs
+ )
}
+
+ computedArgs.add(wsdlFile.path)
+ wsdlToArgs[wsdlFile.path] = computedArgs
+ }
}
private fun buildDefaultArguments(): MutableList {
val defaultArgs = mutableListOf(
- "-xjc-disableXmlSecurity",
- "-autoNameResolution",
- "-d",
- sourcesOutputDir.get().toString()
+ "-xjc-disableXmlSecurity",
+ "-autoNameResolution",
+ "-d",
+ sourcesOutputDir.get().toString()
)
if (suppressGeneratedDate.get()) {
@@ -192,10 +195,10 @@ abstract class Wsdl2JavaTask @Inject constructor(
if (bindingFile.isPresent) {
defaultArgs.addAll(
- listOf(
- "-b",
- bindingFile.get().asFile.absolutePath
- )
+ listOf(
+ "-b",
+ bindingFile.get().asFile.absolutePath
+ )
)
}
@@ -214,12 +217,12 @@ abstract class Wsdl2JavaTask @Inject constructor(
if (options.isPresent || includesWithOptions.isPresent) {
val prohibitedOptions = mapOf(
- "-verbose" to "Configured through the 'verbose' property",
- "-d" to "Configured through the 'generatedSourceDir' property",
- "-p" to "Configured through the 'packageName' property",
- "-suppress-generated-date" to "Configured through the 'suppressGeneratedDate' property",
- "-mark-generated" to "Configured through the 'markGenerated' property",
- "-autoNameResolution" to "Configured automatically and cannot currently be overridden"
+ "-verbose" to "Configured through the 'verbose' property",
+ "-d" to "Configured through the 'generatedSourceDir' property",
+ "-p" to "Configured through the 'packageName' property",
+ "-suppress-generated-date" to "Configured through the 'suppressGeneratedDate' property",
+ "-mark-generated" to "Configured through the 'markGenerated' property",
+ "-autoNameResolution" to "Configured automatically and cannot currently be overridden"
)
// Note that we allow specifying binding file(s) through the -b parameter, as we otherwise can't configure individual bindings pr. wsdl
diff --git a/src/test/kotlin/com/github/bjornvester/IntegrationTest.kt b/src/test/kotlin/com/github/bjornvester/IntegrationTest.kt
index e433119..183cf32 100644
--- a/src/test/kotlin/com/github/bjornvester/IntegrationTest.kt
+++ b/src/test/kotlin/com/github/bjornvester/IntegrationTest.kt
@@ -12,52 +12,33 @@ import java.lang.management.ManagementFactory
import java.util.stream.Stream
open class IntegrationTest {
- @ParameterizedTest(name = "Test plugin with Java version {0} and Gradle version {1}")
+ @ParameterizedTest(name = "Test plugin with Gradle version {0}")
@MethodSource("provideVersions")
- fun thePluginWorks(javaVersion: String, gradleVersion: String, @TempDir tempDir: File) {
- runGenericBuild(javaVersion, gradleVersion, tempDir)
+ fun thePluginWorks(gradleVersion: String, @TempDir tempDir: File) {
+ runGenericBuild(gradleVersion, tempDir)
}
- private fun runGenericBuild(javaVersion: String, gradleVersion: String, tempDir: File) {
+ private fun runGenericBuild(gradleVersion: String, tempDir: File) {
copyIntegrationTestProject(tempDir)
// Remove the "includedBuild" declaration from the settings file
tempDir.resolve(SETTINGS_FILE).writeText(tempDir.resolve(SETTINGS_FILE).readText().replace("includeBuild(\"..\")", ""))
- if (GradleVersion.version(gradleVersion) < GradleVersion.version("7.0")) {
- // The grouping functionality is not supported in older versions
- tempDir.resolve(SETTINGS_FILE)
- .writeText(tempDir.resolve(SETTINGS_FILE).readText().replace("\"grouping-test\",", ""))
+ if (GradleVersion.version(gradleVersion) < GradleVersion.version("8.1")) {
+ // The Gradle configuration cache was not stable until version 8.1
+ tempDir.resolve(PROPERTIES_FILE)
+ .writeText(tempDir.resolve(PROPERTIES_FILE).readText().replace("org.gradle.configuration-cache=true", ""))
}
- if (javaVersion.toInt() < 17) {
- // CXF 4 projects do not support Java < 17
- val settingsContent = tempDir.resolve(SETTINGS_FILE).readText().replace("""\s*"cxf4:.*""".toRegex(), "")
- tempDir.resolve(SETTINGS_FILE).writeText(settingsContent)
- }
-
- if (GradleVersion.version(gradleVersion) < GradleVersion.version("7.6")) {
- // The Gradle toolchain provisioning is not supported in older versions
- tempDir.resolve(SETTINGS_FILE)
- .writeText(tempDir.resolve(SETTINGS_FILE).readText().replace("""id\("org.gradle.toolchains.foojay-resolver-convention"\).*""".toRegex(), ""))
- }
-
- // Set the Java version
- tempDir.resolve(JAVA_CONVENTIONS_FILE)
- .writeText(
- tempDir.resolve(JAVA_CONVENTIONS_FILE).readText()
- .replace("JavaLanguageVersion.of(8)", "JavaLanguageVersion.of($javaVersion)")
- )
-
GradleRunner
- .create()
- .forwardOutput()
- .withProjectDir(tempDir)
- .withPluginClasspath()
- .withArguments("clean", "check", "-i", "-s", "--no-build-cache")
- .withGradleVersion(gradleVersion)
- .withDebug(isDebuggerAttached())
- .build()
+ .create()
+ .forwardOutput()
+ .withProjectDir(tempDir)
+ .withPluginClasspath()
+ .withArguments("clean", "check", "-i", "-s", "--no-build-cache")
+ .withGradleVersion(gradleVersion)
+ .withDebug(isDebuggerAttached())
+ .build()
}
private fun copyIntegrationTestProject(tempDir: File) {
@@ -78,21 +59,15 @@ open class IntegrationTest {
companion object {
const val SETTINGS_FILE = "settings.gradle.kts"
- const val JAVA_CONVENTIONS_FILE = "buildSrc/src/main/kotlin/com.github.bjornvester.wsdl2java.internal.java-conventions.gradle.kts"
+ const val PROPERTIES_FILE = "gradle.properties"
@JvmStatic
@Suppress("unused")
fun provideVersions(): Stream? {
return Stream.of(
- // Test various versions of Gradle, using Java 8
- // This only tests CXF 3 projects
- Arguments.of("8", "6.7"), // Minimum required version of Gradle
- Arguments.of("8", "7.6.1"),
- Arguments.of("8", "8.1.1"),
- // Test various versions of Java, other than one used above, and using the newest (at this time) version of Gradle
- // This tests both CXF 3 and 4 projects
- Arguments.of("11", "8.1.1"),
- Arguments.of("17", "8.1.1")
+ // Test various versions of Gradle
+ Arguments.of("7.6.1"), // Minimum required version of Gradle
+ Arguments.of("8.1.1")
)
}
}