[] (https://drone.io/github.com/djmijares/gradle-wsdl-plugin/latest)
:boom: :collision:
:exclamation:IMPORTANT PLUGIN ID CHANGES:exclamation:
In compliance with the gradle plugin submission guidelines, this plugin's id is now fully qualified.
It changed from wsdl
to com.github.jacobono.wsdl
. This affects
how you apply the plugin (apply plugin: 'com.github.jacobono.wsdl
)
:boom: :collision:
Gradle plugin that defines some conventions for web service Projects. Eases the manual configuration of web service project by:
:boom: :collision:
Now in the gradle plugins repo :exclamation:
:boom: :collision:
plugins {
id 'com.github.jacobono.wsdl' version '1.7.8'
}
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.github.jacobono:gradle-wsdl-plugin:1.7.8'
}
}
apply plugin: 'com.github.jacobono.wsdl'
You need the jaxws configuration to run the wsimport
task, but that is the
only task that has an external dependency. Any version of jaxws that you care to
use will work. I try to stay with the latest releases.
dependencies {
jaxws 'com.sun.xml.ws:jaxws-tools:2.2.8-promoted-b131'
jaxws 'com.sun.xml.ws:jaxws-rt:2.2.8-promoted-b131'
}
wsimport
wsimport
before you
package up a war
war
build
task
automatically!The war would look like this (see the hello-world-episode-binding-ws project in the examples folder)
drwxr-xr-x 0 20-Jan-2013 21:19:26 META-INF/
-rw-r--r-- 25 20-Jan-2013 21:19:26 META-INF/MANIFEST.MF
drwxr-xr-x 0 20-Jan-2013 21:19:26 WEB-INF/
drwxr-xr-x 0 20-Jan-2013 21:19:26 WEB-INF/classes/
drwxr-xr-x 0 19-Jan-2013 21:00:16 WEB-INF/classes/helloworld/
drwxr-xr-x 0 19-Jan-2013 21:00:16 WEB-INF/classes/helloworld/sample/
drwxr-xr-x 0 19-Jan-2013 21:00:16 WEB-INF/classes/helloworld/sample/ibm/
drwxr-xr-x 0 19-Jan-2013 21:00:16 WEB-INF/classes/helloworld/sample/ibm/com/
-rw-r--r-- 993 19-Jan-2013 21:00:16 WEB-INF/classes/helloworld/sample/ibm/com/HelloWorld.class
-rw-r--r-- 2194 19-Jan-2013 21:00:16 WEB-INF/classes/helloworld/sample/ibm/com/HelloWorldService.class
-rw-r--r-- 1837 19-Jan-2013 21:00:16 WEB-INF/classes/helloworld/sample/ibm/com/ObjectFactory.class
drwxr-xr-x 0 20-Jan-2013 21:19:26 WEB-INF/lib/
-rw-r--r-- 2674 19-Jan-2013 21:00:14 WEB-INF/lib/hello-world-schema-0.1.jar
drwxr-xr-x 0 20-Jan-2013 21:19:26 WEB-INF/wsdl/
-rw-r--r-- 2049 19-Jan-2013 20:56:44 WEB-INF/wsdl/HelloWorldEpisodeBindingService.wsdl
drwxr-xr-x 0 20-Jan-2013 21:19:26 WEB-INF/schema/
drwxr-xr-x 0 20-Jan-2013 21:19:26 WEB-INF/schema/HelloWorld/
-rw-r--r-- 581 19-Jan-2013 20:56:44 WEB-INF/schema/HelloWorld/HelloWorld.xsd
- ---------- -------- ----------- -------- -----------------------------------------------------------------
wsdl
and schema
folders are auto populated on the fly :)
This is probably the biggest reason for this plugin and what it attempts to do -- have some sort of standard for xsd and wsdl projects that use schema to source generation and episode binding, eliminating document and generated code duplication.
I have seen a few ways of managing schema documents in projects. Some duplicated xsds in the xsd project AND in the wsdl project, so that the WSDL file could see those xsds. Hard. To. Manage.
I have found that the easiest way to keep things DRY is to have two folders at the root of the repository. Which is great, but the same code ended up being replicated for differnet projects, hence the plugin to stop the copypasta.
These are defaulted into the plugin, but you can change the naming convention, the location convention (under a project, not under the root), or change both.
With this folder layout, any subproject can know where the documents are with
project.rootDir
, and the wsdl and xsd imports/includes can be written and
won't ever have to change.
With this convention, you can have any number of schema projects and generate code through jaxb. I wrote a plugin gradle-jaxb-plugin that handles all of the steps listed below.
schema/episodes
This minimizes the duplicate code regeneration like crazy
Look at the examples folder for some examples using the jaxb plugin.
For a WSDL project, there must be at least one WSDL that the project depends on. This file needs to be directly under the wsdl folder. Abstract WSDLs can be saved in subfolder, but the main WSDL for the project requires this location convention.
These conventions are not definable -- the WSDL file MUST:
i.e.
ChuckNorrisRoundhouseKickToTheFaceService.wsdl
The project name MUST also follow these conventions to find the WSDL file correctly:
i.e.
chuck-norris-roundhouse-kick-to-the-face-ws
Applying this plugin to all projects with the -ws
suffix.
subprojects { project ->
if(project.name.endsWith("-ws")) {
apply plugin: 'com.github.jacobono.wsdl'
dependencies {
jaxws 'com.sun.xml.ws:jaxws-tools:2.2.8-promoted-b131'
jaxws 'com.sun.xml.ws:jaxws-rt:2.2.8-promoted-b131'
}
}
}
Listed in the following sections are the default conventions that are possible to override if desired.
There is a nested configuration, with the wsdl
extension being the parent to the
wsimport
extension. You can change these defaults with a closure in your build
script.
wsdl {
...
wsimport {
...
}
}
There are 4 overridable defaults that declare the location defaults above.
These defaults are changed via the wsdl
closure.
These defaults are changed via the nested wsimport
closure.
Several boolean sensible defaults are defined to be passed into the wsimport task:
verbose
keep
xnocompile
fork
xdebug
xadditionalHeaders
And a few other String defaults
sourceDestionationDirectory
target
wsdlLocation
sourceDestionationDirectory
is relative to project.projectDir
. It defaults to src/main/java
, but can be set to anywhere in the project.projectDir
.
Optional Parameters
encoding
: Set the encoding name for generated sources, such as UTF-8
.
Default value is the platform default (which you really really really don't want if you have developers with different OSs, trust me).package
: The target package name for the generated classes. If left empty, the package name will be derived from the WSDL file.For more information on the jaxws wsimport ant task options, visit here
These are the current default conventions:
wsdl {
wsdlFolder = "wsdl"
schemaFolder = "schema"
episodeFolder = "schema/episodes"
nameRules = [:]
episodes = []
wsimport {
sourceDestinationDirectory = "src/main/java"
verbose = true
keep = true
xnocompile = true
fork = false
xadditionalHeaders = false
xdebug = false
target = "2.1"
wsdlLocation = "FILL_IN_BY_SERVER"
}
}
I have seen WSDL names that can be really long, like REALLY long. This becomes a problem with the project name and wsdl naming conventions. Before you know it, you could have a WSDL file
ProjectNameIsSoLongDataManagementService.wsdl
With a corresponding project name of
project-name-is-so-long-data-management-ws
This is just too long of a project name for me (the WSDL can be that long if that is how it is named, but not the project name)!
A tidy feature I added is something called a "nameRule". This allows you to specify a map of strings to transform in your project name to get the correct wsdl name.
Basically, you can configure the extension closure with something like:
wsdl {
nameRules = ["-dm" : "DataManagement", "-isl" : "IsSoLong"]
}
Now, your project name becomes
project-name-isl-dm-ws
Which is pretty cryptic, yes, but it really reduces the length of your project name. And usually, a project will dictate a Service naming convention like "DataManagement" or "TransactionProcessing" that you can put into a name rule.
I happen to quite like this.
A user can define the episodes wished to be bound (to prevent re-generated
duplicates that have already been generated by the jaxb task). This is the
episodes
property, which is just a list of defined episodes, with their extension.
Configure the wsimport task to bind with episode files located under episodeDirectory
with
wsdl {
episodes = ["name-of-episode-file.episode"]
}
or if there are many episode files,
wsdl {
episodes = ["file1", "file2", "file3"].collect { it + ".episode" }
}
You can find some examples in the examples folder
If you think this plugin could be better, please fork it! If you have an idea that would make something a little easier, I'd love to hear about it.
In my head, I see a few possible improvements