Why can't I call the file() method of an ant taskdef?

While invoking an Ant taskdef, why does this particular case require a closure?

I’m using the Closure Compiler ant task, example usage (from http://code.google.com/p/closure-compiler/wiki/BuildingWithAnt):

<taskdef name=“jscomp” classname=“com.google.javascript.jscomp.ant.CompileTask”

classpath="…/build/compiler.jar"/> <target name=“compile”>

<jscomp compilationLevel=“simple” warning=“verbose”

debug=“false” output=“output/file.js”>

<sources dir="${basedir}/other">

<file name=“stacktrace.js”/>

</sources>

</jscomp> </target>

Converting to Gradle:

task minify << {
 description = 'minify JS file'
  project.ant {
  ant.taskdef(name: 'jscomp',
     classname: 'com.google.javascript.jscomp.ant.CompileTask',
    classpath: configurations.js.asPath)
    jscomp(compilationLevel: 'simple', warning: 'quiet', debug: 'false', output: minifiedFilePath) {
   sources(dir: srcDir) {
                                //file(name: 'stacktrace.js') does not work. Shouldn't it?
    file(name: 'stacktrace.js'){} // Why do I need the curly braces here?
   }
  }
 }
}

I’ve used other ant tasks and the structure of closures made sense. But, I beat my head against a wall, a desk and my monitor for a couple hours to figure this one out, so I was just curious to know why.

Do you have a stack trace for the broken version?

Sorry about my late update here.

This makes perfect sense because of the built-in file() method for Gradle.

Thanks a bunch

Eric,

It’s because the ultimate owner of the closure (the Project instance) actually implements the file(Object) method, so that is taking precedence over the method from the ant task.

Another solution would be:

task minify << {
    description = 'minify JS file'
     project.ant {
        ant.taskdef(name: 'jscomp',
                 classname: 'com.google.javascript.jscomp.ant.CompileTask',
                classpath: configurations.js.asPath)
        jscomp(compilationLevel: 'simple', warning: 'quiet', debug: 'false', output: minifiedFilePath) {
            sources(dir: srcDir) {
                delegate.file(name: 'stacktrace.js')
            }
        }
    }
}

To force the method to be called on the closure delegate, which is the ant task.