Weird behavior of custom task creating directory

I have a custom task that needs a directory to be created under build directory.

task customTask() {
File newDir = new File("$buildDir/newDir")
newDir.mkdirs();
//do rest of the things
}

I have made compileJava dependsOn customTask. If i run gradle build or gradle customTask, i seem to have no issues. If i do gradle clean build, the directory is not getting created and the rest of the task fails.

I dont have this issue if i change my code to the following by marking the task as doLast.

task customTask() << {
File newDir = new File("$buildDir/newDir")
newDir.mkdirs();
//do rest of the things
}

can someone please explain the behavior?

When your code is not contained in a doLast, then it is executed during the configuration phase. After the configuration phase is complete the task graph is executed. Since clean is in that task graph, it deletes the build directory, which you just added to.

Moving your code into a doLast results in the code being delayed until customTask is executed, as opposed to configured above.

I recommend studying the build lifecycle chapter in the userguide. It contains an example that demonstrates the different points of code execution.