我是新手并尝试迁移我们当前基于Maven的自动化JAX-WS客户端构建项目,因为gradle似乎为我们提供了一种更简单的方法来为新项目配置构建。
我遵循了本教程here,并能够为WSDL端点生成客户端类。我现在想要实现的是将Task定义放在一个新的DefaultTask类中以保持build.gradle文件更清晰,所以我创建了以下文件,将它放在一个新的Groovy项目中并使其可用于我的构建:
class WsimportTask extends DefaultTask {
def List<String> wsdlUrls
@OutputDirectory
File destDir
@TaskAction
def wsimport() {
wsdlUrls.each() {
println "run wsimport for "+ it
ant {
sourceSets.main.output.classesDir.mkdirs()
destDir.mkdirs()
taskdef(name:'wsimport',
classname:'com.sun.tools.ws.ant.WsImport',
classpath:configurations.jaxws.asPath)
wsimport(keep:true,
destdir: sourceSets.main.output.classesDir,
sourcedestdir: destDir,
wsdl: it)
}
}
}
}
由于我想要为我们拥有的每个Web服务客户端提供一个包含子项目的项目,我更改了主项目的build.gradle文件并添加了:
main build.gradle
subprojects {
configurations {
wsimport
}
dependencies {
wsimport group: 'com.mycompany.gradle', name: 'tasks', version: '0.0.2-SNAPSHOT'
}
task wsimport(type: com.mycompany.gradle.WsimportTask) {
destDir = file("${buildDir}/generated")
}
compileJava.dependsOn(wsimport)
}
子项目本身应该只需要包含以下配置:
子项目build.gradle
buildscript {
wsimport {
wsdlUrls = [
"http://...endpoint1.wsdl",
"http://...endpoint2.wsdl"
]
}
}
在主项目上运行gradle clean build时,我收到以下消息和Exception:
:clean UP-TO-DATE
:Subproject:clean
:Subproject:wsimport
run wsimportfor http://endpoint1.wsdl
:Subproject:wsimport
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':Subproject:wsimport'.
....
FAILED Caused by: org.gradle.api.internal.MissingMethodException: Could not find method ant() for arguments [com.mycompany.gradle.WsimportTask$_wsimport_closure1_closure2@16caac05] on task ':Subproject:wsimport'.
因此gradle了解我的配置,应用WSDL端点并调用我的自定义任务。然后将ant {}计算到本地方法,调用方法ant(),该方法不存在。这对我来说非常有意义,但是我怎样才能实现从这个自定义gradle任务中调用实际的ant wsimport任务的目标呢?
解决方案感谢Peter的回答。我想我确实开始理解Task如何连接到我的构建脚本。我为未来的斗争者粘贴了完整的任务,因为我不认为创建这样一个任务的整个过程(特别是第一次)有点难以理解:
class WsimportTask extends DefaultTask {
def List<String> wsdlUrls
@OutputDirectory
File outDir
@TaskAction
def wsimport() {
wsdlUrls.each() {
def temp = it
println "run wsimport for "+ temp
project.sourceSets.main.output.classesDir.mkdirs()
outDir.mkdirs()
def classpath = project.configurations.jaxws.asPath
def destDir = project.sourceSets.main.output.classesDir
project.ant {
taskdef(name:'wsimport',
classname:'com.sun.tools.ws.ant.WsImport',
classpath:classpath)
wsimport(keep:true,
destdir: destDir,
sourcedestdir: outDir,
wsdl: temp)
}
}
}
}
值得注意的是,必须不在build.gradle文件的buildscipt块中定义任务,就像Peter指出的那样
答案 0 :(得分:2)
与构建脚本不同,任务或插件类没有隐式Project
上下文。因此,它是project.ant
,project.file
等。此外,必须在buildscript
块之外声明和配置任务(请参阅子项目build.gradle
)。
答案 1 :(得分:0)
试试这个:
@TaskAction
def wsimport() {
wsdlUrls.each() {
println "run wsimport for "+ it
sourceSets.main.output.classesDir.mkdirs()
destDir.mkdirs()
ant.taskdef(name:'wsimport',
classname:'com.sun.tools.ws.ant.WsImport',
classpath:configurations.jaxws.asPath)
ant.wsimport(keep:true,
destdir: sourceSets.main.output.classesDir,
sourcedestdir: destDir,
wsdl: it)
}
}