Copy action is leaving source file handle open

I have, in one of my plugins, in a base Task class, some logic that all tasks derived from this base do on completion:

        doLast {
            if (project != project.rootProject ) {
                project.copy {
                    into (project.rootProject.buildDir)
                    from this.outputs
                }
            }    
        }

This has the side effect, that once this has been run in one build from Eclipse on Windows, the clean task cannot be run in a subsequent build, because the source file handle is still open. Running Microsoft’s Process Explorer, the source file is shown to be open. The destination file is NOT shown to be open. If I try to delete the source file in Eclipse, it cannot be done. If I try to delete the file from outside Eclipse, while Eclipse is still running, it cannot be done.

If I exit Eclipse, then the file can be deleted. When running this build from the command line, there is no such issue. The file can be deleted using clean, direct OS rm commands, etc.

This is happening with Gradle 2.14 and earlier versions, and has been happening for awhile, in both Eclipse Luna and Mars and several releases of buildship, up to the latest. I suppose I first noticed it a couple of months ago, when I started actually running gradle builds in Eclipse instead of just using it as an editor.

I have tagged this with the buildship tag, but I’m not sure it’s buildship’s fault. My guess is that the standard gradle code is not closing the file, and can get away with this because the problem goes away when the gradle process ends, as it usually soon does. But in Eclipse, the file handle is owned by the java process that launched Eclipse and this process does not terminate when the build ends. There might be a solution to be found in buildship, but probably the copy action source implied by this.outputs needs to explicitly close the file.

Hey Steve,

this is probably a file locking issue in the daemon. Can you give 3.0 M2 a shot and see whether that works for you? We’ve been putting a lot of effort into fixing these kinds of issues, so we can enable the daemon by default.

Cheers,
Stefan

Sorry, but I’ve given 3.0 M2 a shot and find the problem persisting with that version.

Are you using the daemon on the command line?

I’m running this build in Eclipse, not from the command line, which is where the problem lies. The project is using the gradle wrapper. My ${HOME}/.gradle/gradle.properties has

org.gradle.daemon=true.

I suppose that means the daemon is running. How would I tell for sure?

With debug logging on I see:

12:48:40.181 [DEBUG] [org.gradle.launcher.daemon.server.exec.ExecuteBuild] The daemon has started executing the build.

So I guess answer is yes.

So with 2.14, on the command line, with the daemon enabled, you are not seeing this problem? I’m asking because it’s very unlikely that this is caused by Buildship itself. If the daemon is enabled, you should be seeing the same behavior on the command line.

So with 2.14, on the command line, with the daemon enabled, you are not seeing this problem?

As unlikely as it may seem, that is correct. I only see the problem in Eclipse. The daemon is definitely running in both places. I have org.gradle.daemon=true in gradle.properties.

I agree with you that it’s not likely buildship’s fault. I suspect it may have more to do with what my little block of code is doing, and how streams are being closed in that situation, than with the daemon. Could you try attaching my block of code to some project and see if it can be replicated?

Would it help to know which process has the file handle left open? This can be done using SysInternal’s Process Explorer.

The process is java.exe and it goes away when Eclipse is closed.

That might be conclusive, but I would assume there are multiple java.exe processes in scope here. Is it the java process running Eclipse (which you can tell from the full command line, often difficult to tell without using Process Explorer), or something else?

Anyway, it might be moot. I was just pointing out you could determine which process has the file handle. I don’t know enough about the problem to tell whether that matters here or not. If it’s irrelevant, you can close this line of inquiry.

When I do this, there is only one java.exe process shown in TaskManager, and it goes away when Eclipse closes, so it is pretty conclusive that that is Eclipse.

Update with more accurate information:

I’d been using, inaccurately, “command-line”, as a synonym for “running gradle on unix”.

I think the problem actually has to do with the implementation of the gradle daemon on Windows, whether using Eclipse, cmd, or using git-bash on Windows. Command-line windows was not something I’d tried previously but now I find that the problem persists with the code at the top of this post in every windows version including 2.14, 2.14.1 and 3.0, either from Eclipse or command lines with the daemon running. Stopping the daemon (or its java.exe process) kills the file handle. On unix, the problem does not exist.

Bottom line:
It’s a problem with

  • the code shown above
  • on any version of gradle up to and including 3.0
  • running on Windows (not unix)
  • if the daemon is running

Update: This was not correct. The problem exists in Eclipse or the command line, under Windows only.

This entire issue may now be put to rest. It has nothing to do with Copying the file. Gradle’s code is perfectly blameless. My code that copied the file was perfectly blameless as well.

The problem has to do with the Nebula RPM plugin. Hard as it may be to believe, that plugin is not closing the RPM file it builds!

See https://github.com/nebula-plugins/gradle-ospackage-plugin/issues/200

1 Like

Thank you for getting to the bottom of this Steve :thumbsup: