1. <groovy>
| 在此,我们描述了一个 Ant 任务,用于在 Ant 构建文件中使用 Groovy。您可能还对 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>如果您的任何模块通过 classpath 加载服务(例如 groovy-json),您可能需要使用 contextClassLoader 属性(见下文)。
3. <groovy> 属性
| 属性 | 描述 | 必需 | 
|---|---|---|
| src | 包含 Groovy 语句的文件。包含该文件的目录将添加到 classpath 中。 | 是,除非语句包含在标签内 | 
| classpath | 要使用的 classpath。 | 不 | 
| classpathref | 要使用的 classpath,作为对其他地方定义的 PATH 的引用。 | 不 | 
| output | 设置输出文件;默认为 Ant 日志。 | 不 | 
| append | 如果启用且输出到文件,则附加到现有文件而不是覆盖。默认为 false。 | 不 | 
| fork | 如果启用,脚本将在分叉的 JVM 进程中执行(默认为禁用)。 | 不 | 
| scriptBaseClass | 脚本基类的名称。 | 不 | 
| parameters | 在 JDK 8 及更高版本上为方法参数名称的反射生成元数据。默认为 false。 | 不 | 
| useGroovyShell | 如果启用,将使用新的 GroovyShell 运行脚本。特殊变量将不可用,但您不需要 Ant 在 classpath 中。默认为 false。 | 不 | 
| includeAntRuntime | 如果启用,在分叉时,系统 classpath 将包含在 classpath 中。默认为 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 | 一个  | 
| 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