1. <groovy>
本节介绍如何在 Ant 构建文件中使用 Groovy 的 Ant 任务。您可能还对 Ant 的内置 script 任务感兴趣,该任务支持 Groovy 和其他语言,或者 AntBuilder ,它允许您使用 Groovy 而不是 XML 编写 Ant 构建脚本。 |
从 Apache Ant 中执行一系列 Groovy 语句。语句可以从资源中读取,也可以作为包含在 Groovy 标记之间的直接文本。
2. 必要的 taskdef
假设您需要的所有 groovy jar 都在 my.classpath 中(这将是 groovy-VERSION.jar
、groovy-ant-VERSION.jar
以及您可能正在使用的任何模块和传递依赖项),您需要在 build.xml
中的某个地方声明此任务,并在调用 groovy
任务之前。
<taskdef name="groovy"
classname="org.codehaus.groovy.ant.Groovy"
classpathref="my.classpath"/>
您可以像这样简单地在 groovy
标记之间放置语句
<groovy>
...
</groovy>
或者,您可以将 Groovy 源脚本作为资源提供。您可以使用 src
属性指定路径名,如下所示
<groovy src="/some/path/MyGroovyScript.groovy" otherAttributes="...">
或者作为嵌套的 fileset
,如下所示(尽管预计 fileset 定义只会选择一个文件)
<groovy>
<fileset file="MyGroovyScript.groovy"/>
</groovy>
或者作为嵌套的单个元素 资源集合,它可能看起来像以下任何一种
<groovy>
<file file="MyGroovyScript.groovy"/>
</groovy>
<groovy>
<url url="https://some.domain/some/path/to/MyGroovyScript.groovy"/>
</groovy>
<groovy>
<javaconstant name="some.packagename.SomeClass.MY_CODE_FRAGMENT"/>
</groovy>
您也可以提供一个 过滤器链,如下所示
<groovy>
<fileset file="MyGroovyScript.groovy"/>
<!-- take 5 lines after skipping 18 lines, just as an example -->
<filterchain>
<headfilter lines="5" skip="18"/>
</filterchain>
</groovy>
如果您的任何模块通过类路径加载服务(例如 groovy-json
),您可能需要使用 contextClassLoader 属性(见下文)。
3. <groovy>
属性
属性 | 描述 | 必需 |
---|---|---|
src |
包含 Groovy 语句的文件。包含该文件的目录将被添加到类路径中。 |
是,除非在标记内包含语句 |
classpath |
要使用的类路径。 |
否 |
classpathref |
要使用的类路径,作为对在其他地方定义的 PATH 的引用给出。 |
否 |
output |
设置输出文件;默认为 Ant 日志。 |
否 |
append |
如果启用且输出到文件,则追加到现有文件而不是覆盖。默认为 false。 |
否 |
fork |
如果启用,则脚本将在一个分叉的 JVM 进程中执行(默认情况下禁用)。 |
否 |
scriptBaseClass |
脚本基类的名称。 |
否 |
parameters |
在 JDK 8 及更高版本上为方法参数名称的反射生成元数据。默认为 false。 |
否 |
useGroovyShell |
如果启用,则使用一个新的 GroovyShell 来运行脚本。特殊变量将不可用,但您不需要将 Ant 放在类路径中。默认为 false。 |
否 |
includeAntRuntime |
如果启用,则在分叉时将系统类路径包含在类路径中。默认为 true。 |
否 |
stacktrace |
如果启用,则在编译期间发生错误时将报告堆栈跟踪。默认为 false。 |
否 |
configScript |
设置 groovy 编译器配置的配置脚本。 |
否 |
contextClassLoader |
如果启用,则将上下文类加载器设置为用于运行脚本的 shell 的类加载器。如果 fork 为 true,则不使用。 |
否 |
4. 作为嵌套元素指定的参数
4.1. <classpath>
Groovy 的 classpath 属性是一个类似 PATH 的结构,也可以通过嵌套的 classpath 元素设置。
4.2. <arg>
可以使用一个或多个嵌套的 <arg>
元素通过标准 Ant 命令行约定 设置参数。
5. 可用绑定
在您的 Groovy 语句中可以使用许多绑定。
名称 | 描述 |
---|---|
ant |
了解当前 ant 项目的 |
project |
当前的 ant 项目 |
properties |
ant 属性的 |
target |
调用此 groovy 脚本的拥有目标 |
task |
包装任务,可以访问 |
args |
命令行参数(如果有) |
6. 示例
Hello world,版本 1
<groovy>
println "Hello World"
</groovy>
Hello world,版本 2
<groovy>
ant.echo "Hello World"
</groovy>
列出当前目录中的所有 xml 文件
<groovy>
xmlfiles = new File(".").listFiles().findAll{ it =~ "\.xml$" }
xmlfiles.sort().each { println it.toString() }
</groovy>
列出 jar 中的所有 xml 文件
<zipfileset id="found" src="foobar.jar"
includes="**/*.xml"/>
<groovy>
project.references.found.each {
println it.name
}
</groovy>
运行脚本
<groovy src="/some/directory/some/file.groovy">
<classpath>
<pathelement location="/my/groovy/classes/directory"/>
</classpath>
</groovy>
查找目录中所有 jar 中具有 org.*
包的 Builder
类
<property name="local.target" value="C:/Projects/GroovyExamples"/>
<groovy>
import java.util.jar.JarFile
def classes = []
def resourceNamePattern = /org\/.*\/.*Builder.class/
def jarNamePattern = /.*(beta|commons).*jar$/
def libdir = new File("${properties['local.target']}/lib")
libdir.listFiles().grep(~jarNamePattern).each { candidate ->
new JarFile(candidate).entries().each { entry ->
if (entry.name ==~ resourceNamePattern) classes += entry.name
}
}
properties["builder-classes"] = classes.join(' ')
</groovy>
<echo message='${builder-classes}'/>
这可能会导致以下结果
org/apache/commons/cli/PatternOptionBuilder.class org/apache/commons/cli/OptionBuilder.class org/codehaus/groovy/tools/groovydoc/GroovyRootDocBuilder.class org/custommonkey/xmlunit/HTMLDocumentBuilder.class org/custommonkey/xmlunit/TolerantSaxDocumentBuilder.class
FileScanner 版本(在收集名称方面略有不同)
<groovy>
import java.util.jar.JarFile
def resourceNamePattern = /org\/.*\/.*Builder.class/
def candidates = ant.fileScanner {
fileset(dir: '${local.target}/lib') {
include(name: '*beta*.jar')
include(name: '*commons*.jar')
}
}
def classes = candidates.collect {
new JarFile(it).entries().collect { it.name }.findAll {
it ==~ resourceNamePattern
}
}.flatten()
properties["builder-classes"] = classes.join(' ')
</groovy>
从您的 Ant 脚本中调用 Web 服务
<?xml version="1.0" encoding="UTF-8"?>
<project name="SOAP example" default="main" basedir=".">
<property environment="env"/>
<property name="celsius" value="0"/>
<target name="main">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy">
<classpath>
<fileset dir="${env.GROOVY_HOME}" includes="lib/groovy-*.jar,lib/ivy*.jar"/>
</classpath>
</taskdef>
<groovy>
@Grab('org.codehaus.groovy.modules:groovyws:0.5.1')
import groovyx.net.ws.WSClient
def url = 'https://w3schools.org.cn/webservices/tempconvert.asmx?WSDL'
def proxy = new WSClient(url, this.class.classLoader)
proxy.initialize()
ant.echo "I'm freezing at ${properties.celsius} degrees Celsius"
properties.result = proxy.CelsiusToFahrenheit(properties.celsius)
</groovy>
<antcall target="results"/>
</target>
<target name="results">
<echo message="I'm freezing at ${result} degrees Fahrenheit"/>
</target>
</project>
这将输出以下内容(以及一些信息性消息)
main:
...
[echo] I'm freezing at 0 degrees Celsius
results:
[echo] I'm freezing at 32 degrees Fahrenheit
BUILD SUCCESSFUL
设置参数
<target name="run">
<groovy>
<arg line="1 2 3"/>
<arg value="4 5"/>
println args.size()
println args[2]
args.each{ ant.echo(message:it) }
</groovy>
</target>
输出
Buildfile: build.xml
run:
[groovy] 4
[groovy] 3
[echo] 1
[echo] 2
[echo] 3
[echo] 4 5
BUILD SUCCESSFUL