Supposing that SElinux is not involved, here's some analysis under traditional UNIX semantics. (I'll post another comment relevant to SElinux.)
The ETXTBSY error code from execve(2) happens when the executable (in this case, a shell script) is still opened for write by another process. Reading the kernel code there does not appear to be any chance for a "slight delay"; when the writer calls close() the atomic inode->i_readcount is decremented, and open_exec() correctly tests the atomic against zero.
So I strongly suspect that the writer does, in fact, still have the filedescriptor open for write when the execve happens.
I don't see how that's possible, though – we clearly call w.close() in the finally clause of writeCommand, and I don't see anywhere that we leak a FileDescriptor to prevent FileOutputStream#close from triggering the underlying close(2).
We can avoid the ETXTBSY by avoiding the execve. If I'm reading launchTask correctly, the script we're execing isn't even a valid shell script anyways – it's just a sequence of shell commands, without the leading "#!/bin/sh" header. By running it bash -c "/path/to/script" we're relying on the ancient pre-Bourne shell script convention that if execve() fails with ENOEXEC, the shell tries to interpret the file as a script.
Instead, we can ask bash to directly run the script as a script by running bash "/path/to/script" leaving out the -c. This avoids the code path that triggers the ETXTBSY failure and is slightly less reliant on random backwards compatibility kludges. And it doesn't break if we do have the #!/bin/sh line since that's just a comment.
Now, suppose the undiscovered but hypothesized race condition in writeCommand does exist, and affects the write as well as the close. Then removing -c does not remove the race, and when we lose the race the failure will probably be more silent. The command file might not be completely written and running the script might fail.