Up-to-date check ignores the files generated in the previous task

Hi, I appear to be having issues with generated files and Gradle, I think it is due to SkipEmptySourceFilesTaskExecuter. When the generateJavaFromIdl task below is run it generates a number of files that go to src/generated. When compileGeneratedJava runs directly afterwards it does not see the java files in src/generated for some reason.

Should I be generating these files under build? Are there any work-arounds for the issue? Or am I just doing something silly?

Thanks, Steve

Here is an anonymised build.gradle:

apply plugin: 'java'
    task generateJavaFromIdl() {
  doLast {
    delete destination
    fileTree(source).each { def fileInstance ->
      String command = System.getenv().get("IDL_COMPILER_DIR")+'/bin/idlCompiler -outDir ' + destination.absolutePath + " " + fileInstance.absolutePath
      println "Generating Java source from ${fileInstance}"
      command.execute()
    }
  }
}
generateJavaFromIdl.ext.source = file('src/idl')
generateJavaFromIdl.inputs.dir generateJavaFromIdl.ext.source
generateJavaFromIdl.ext.destination = file('src/generated')
generateJavaFromIdl.outputs.dir generateJavaFromIdl.ext.destination
    sourceSets {
  generated {
    java {
      srcDir file('src/generated')
    }
  }
  test {
    java {
      srcDir file('src/test')
    }
  }
}

The behaviour I see is as follows:

16:13:15.692 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter] Executing actions for task ‘:generateJavaFromIdl’. 16:13:15.695 [DEBUG] [org.gradle.api.internal.file.copy.DeleteActionImpl] Deleting /src/generated 16:13:15.775 [QUIET] [system.out] Generating Java source from /src/idl/Example.idl 16:13:15.823 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ‘:generateJavaFromIdl’ 16:13:15.829 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :generateJavaFromIdl (Thread[main,5,main]) completed. Took 0.244 secs. 16:13:15.830 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :compileGeneratedJava (Thread[main,5,main]) started. 16:13:15.832 [LIFECYCLE] [org.gradle.TaskExecutionLogger] :compileGeneratedJava 16:13:15.834 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Starting to execute task ‘:compileGeneratedJava’ 16:13:15.837 [INFO] [org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter] Skipping task ‘:compileGeneratedJava’ as it has no source files. 16:13:15.838 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ‘:compileGeneratedJava’ 16:13:15.840 [LIFECYCLE] [org.gradle.TaskExecutionLogger] :compileGeneratedJava UP-TO-DATE

I forgot to say, running ‘gradle -debug compileTestJava’ a second time directly afterwards will cause the compileGeneratedJava task to run through correctly, it is as if it is checking the file system for changes at the start of the build as opposed to just before executing the task.

I can’t spot the problem. The “skip” check is performed immediately before the task runs, not any earlier. I’d try to list the ‘src/generated’ dir immediately after ‘command.execute()’ to see what’s there.

Some additional hints, even though they don’t seem to cause the problem:

  • The task dependency ‘compileGeneratedJava.dependsOn(generateJavaFromIdl)’ needs to be established. * Generated code should definitely go under ‘build’. * Code that reads (rather than writes) an extra variable should omit ‘ext.’.

Right, I have cracked it. It appears that it is due to the files output by the IDL compiler not being ready when the check is done. I have put a Thread.sleep(1000) after the IDL generation and it now detects the changes correctly.

I will have a think about better ways this could be done, I am not keen on the idea of a wait in there. Initially I was working on a network drive but working in /tmp also still needed the wait.

Thanks for the tips, much appreciated.

Steve