UncheckedIOException with file copy

Hi! I’m just trying to do something dead simple. I want to copy a single file to a new name in the same directory. I try:

task myCopy(type: Copy) {
    from 'test.xml'
    into projectDir
    rename { 'test2.xml'}
 }

but I get:

Exception is: org.gradle.api.UncheckedIOException: java.io.IOException: The process cannot access the file because another process has locked a portion of the file

I’m sure I’m not understanding something basic. Any help would be appreciated.

  • Todd

Does it work when you copy to/from a directory other than ‘projectDir’?

Yes. This works:

task myCopy(type: Copy) {
    from 'test.xml'
    into 'newdir'
    rename { 'test2.xml'}
}

The problem is only when I try to copy to the same directory.

Hmm…

I copied the project to a Linux server and the code worked as expected!

It looks like there’s a bug in Gradle’s Copy task under Windows XP. The developers here work in XP, so I guess I’ll have to use the ant copy task until it gets fixed.

Does it work when you copy to/from the same directory but not ‘projectDir’?

Yes. This works fine:

task myCopy(type: Copy) {
    from 'newdir/test2.xml'
    into 'newdir'
    rename { 'test3.xml'}
}

So it only seems to be a problem copying around in the project directory. My solution (for now):

ant.copy(file: 'test.xml', tofile: 'test2.xml' )

Actually, now that I look at it, the ant call is clearer and more concise. I think I’ll just use that from now on.

So, I found that this issue must have been fixed, in gradle 1.9 or earlier, at least partially. I am experiencing similar file locking issues on a simple copy and rename to the rootProject’s directory, within a multi-project build.

task copyMasterMakefile(type: Copy) {
    from masterMakefile
    into rootProject.getProjectDir()
    rename {'Makefile'}
}
$ gradlew copyMasterMakefile
:oldBuildscripts:copyMasterMakefile
  FAILURE: Build failed with an exception.
  * What went wrong:
java.io.IOException: The process cannot access the file because another process has locked a portion of the file
> The process cannot access the file because another process has locked a portion of the file

Sorry to reopen this thread. I wasn’t sure if there was an issue that I could post this to.

As I said, the single file copy and rename to the subproject’s directory works as expected.

task copyMasterMakefile(type: Copy) {
    from masterMakefile
    into getProjectDir()
    rename {'Makefile'}
}
$ cat gradle/wrapper/gradle-wrapper.properties
| grep distributionUrl
distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-bin.zip
$ gradlew copyMasterMakefile
:oldBuildscripts:copyMasterMakefile
  BUILD SUCCESSFUL
  Total time: 7.737 secs
$ ls -larth subprojects/old-buildscripts/Makefile
-rw-r--r--
  1 kevinm
 Administ
    19k Jan
9 14:04 subprojects/old-buildscripts/Makefile

Kevin,

Could you supply a self contained build that exhibits the problem?

Sure. I’ll work on it and get back to you.

Reproducible test case for my rootProject locking issue

…yes, I’m on windows, despite the fact that I like to work in a bash shell :slight_smile:

  • Project setup:
kevinm@xxx /d/repos/temp
$ gradle init
:wrapper
:init
  BUILD SUCCESSFUL
  Total time: 3.306 secs
kevinm@xxx /d/repos/temp
$ mkdir foo
kevinm@xxx /d/repos/temp
$ cd foo
kevinm@xxx /d/repos/temp/foo
$ echo "foobar" > foo.txt
  • Modify settings.gradle:
...
/*
// To declare projects as part of a multi-project build use the 'include' method
include 'shared'
include 'api'
include 'services:webservice'
*/
  rootProject.name = 'temp'
include 'foo'
  • Modify foo’s build.gradle (e.g. ‘d:\repos\temp\foo\build.gradle’):
ext {
    afile = 'foo.txt'
}
  task copyFile(type: Copy) {
    from afile
    into rootProject.getProjectDir()
}
  • Run gradle wrapper with ‘copyFile’ task:
kevinm@xxx /d/repos/temp
$ gradlew copyFile
:foo:copyFile
  FAILURE: Build failed with an exception.
  * What went wrong:
java.io.IOException: The process cannot access the file because another process has locked a portion of the file
> The process cannot access the file because another process has locked a portion of the file
  * Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
  BUILD FAILED
  Total time: 5.679 secs

I hope that helps. Let me know if this still isn’t reproducible. I would love for this to be some dumb environmental issue on my end. :wink:

I’ve also wondered if specifying the ‘into’ property as ‘rootProject.getProjectDir()’ may be the issue, but I wasn’t quite sure how else to get that value. That is proper usage, correct?

in general passing rootProject.getProjectDir should work fine

Hello Kevin,

many thanks for the self-contained example. I can reproduce this problem now and will create an issue for that in the gradle issue tracker.

task myCopy{

doLast{

copy {

from ‘buildscript/templates/’

into ‘.’

include ‘**/*’

}

} }

This might work for you as it works for me.

Thanks @kingkong.

This works. This is the only workaround I found so far. However, be sure to specify task’s inputs and outputs unless what, the copy will always occur.

task copyToProjectDir() {
   inputs.file "/path/to/Makefile"
  outputs.file "$projectDir/Makefile"
    doLast {
    copy {
      from "/path/to/Makefile"
      into projectDir
    }
   }
}

This works for explicit files, but will fail with the same error if outputs is the project directory directly like ‘outputs.dir projectDir’. In this case, we return to the same problem as the ‘Copy’ task.

One solution I thought when copying specific files would be to change custom ‘Copy’ task’s outputs definition to point to a specific file:

task copyToProjectDir(type: Copy) {
  outputs.file "$projectDir/Makefile"
    from "/path/to/Makefile"
  into projectDir
}

But this does not seem to make it, I think because the default outputs inferred by the base ‘Copy’ task are still applied. Maybe it’s possible to completely change task’s outputs? I tried using a ‘upToDateWhen’ with a closure, not much luck.