Why does a task execute even when inputs and outputs are defined and nothing has changed

I’m continuing to play with my Antlr3 build.

task generateGrammarSource(type: JavaExec) {
  description "Generates Java sources from Antlr3 grammars."
  inputs.source fileTree(dir: antlrSource, include: "**/*.g")
  outputs.dir file(antlrOutput)
    classpath configurations.antlr3
    main "org.antlr.Tool"
  args "-o", "${antlrOutput}/org/apache/tapestry5/internal/antlr"
  args inputs.sourceFiles
    doFirst {
    logger.info "Executing Antlr3 grammar generation:\n${commandLine.join(' ')}"
  }
}

Using this task, I can see my code execute perfectly:

:tapestry-core:generateGrammarSource
Executing Antlr3 grammar generation:
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java -cp /Users/hlship/.gradle/caches/artifacts-7/artifacts/56865c09425cc6ecda8606d7e6035ceb/org.antlr/antlr/3.3/jar/antlr-3.3.jar:/Users/hlship/.gradle/caches/artifacts-7/artifacts/56865c09425cc6ecda8606d7e6035ceb/antlr/antlr/2.7.7/jar/antlr-2.7.7.jar:/Users/hlship/.gradle/caches/artifacts-7/artifacts/56865c09425cc6ecda8606d7e6035ceb/org.antlr/stringtemplate/3.2.1/jar/stringtemplate-3.2.1.jar:/Users/hlship/.gradle/caches/artifacts-7/artifacts/56865c09425cc6ecda8606d7e6035ceb/org.antlr/antlr-runtime/3.3/jar/antlr-runtime-3.3.jar org.antlr.Tool -o /Users/hlship/workspaces/tapestry/tapestry5/tapestry-core/build/generated-sources/antlr/org/apache/tapestry5/internal/antlr /Users/hlship/workspaces/tapestry/tapestry5/tapestry-core/src/main/antlr/org/apache/tapestry5/internal/antlr/PropertyExpressionLexer.g /Users/hlship/workspaces/tapestry/tapestry5/tapestry-core/src/main/antlr/org/apache/tapestry5/internal/antlr/PropertyExpressionParser.g

… the problem is, it appears to execute every time. I’m defining an output directory, shouldn’t that be enough? I believe I’m following all the necessary guidelines for task optimization, but it executes my command every time. Is this something special about JavaExec task:

1.0-milestone-7. I’ve attempted this with --no-daemon as well.

From the --debug output, it appears the Gradle thinks the output directory has changed.

For some reason, JavaExec sets upToDateWhen { false } in its constructor. I don’t think that’s good, but it’s the current behavior.

That’s horrendous! I can’t find a workaround, because TaskOutputs doesn’t expose a way to clear or change existing predicates, just add a new one. Why would anyone think that was a good idea?

This looks like a temporary workaround:

outputs.upToDateSpec = new AndSpec();

Thanks for taking the time to update your “feelings”. Makes it interesting!

This is GRADLE-1483