Copy file to UNIX group writable (664) files fails if not the owner

The copy file actually works, but for some reason the code tries to chmod 644 the file immediately afterwards. It fails because I don’t own the file and am not allowed to chmod it.

task deployTest(dependsOn: jar, type: Sync) {
    description 'Deploy Test'
    fileMode null
    from configurations.runtime
    into "/tmp/java_lib"
}

Produces this error if the files in /tmp/java_lib are group writable but owned by someone else.

Caused by: org.gradle.internal.nativeintegration.filesystem.FileException: Could not set file mode  644 on '/tmp/java_lib/annotations-5.1.jar'.
at org.gradle.internal.nativeintegration.filesystem.services.GenericFileSystem.chmod(GenericFileSystem.java:71)
at org.gradle.api.internal.file.AbstractFileTreeElement.copyTo(AbstractFileTreeElement.java:76)
... 77 more
Caused by: net.rubygrapefruit.platform.NativeException: Could not set UNIX mode on /tmp/java_lib/annotations-5.1.jar: could not chmod file (errno 1)
at net.rubygrapefruit.platform.internal.DefaultPosixFiles.setMode(DefaultPosixFiles.java:41)
at org.gradle.internal.nativeintegration.filesystem.services.NativePlatformBackedChmod.chmod(NativePlatformBackedChmod.java:32)
at org.gradle.internal.nativeintegration.filesystem.services.GenericFileSystem.chmod(GenericFileSystem.java:69)
... 78 more

Here’s the code in AbstractFileTreeElement:

        if (isDirectory()) {
            GFileUtils.mkdirs(target);
        } else {
            GFileUtils.mkdirs(target.getParentFile());
            copyFile(target);
        }
        chmod.chmod(target, getMode());

Notice that it chmods the file even though it may not be necessary. getMode() is like this:

public int getMode() {
    return isDirectory()
        ? FileSystem.DEFAULT_DIR_MODE
        : FileSystem.DEFAULT_FILE_MODE;
}

FileSystem.DEFAULT_FILE_MODE = 644.

I’ve tried setting “fileMode 0664” (which is the file’s current permissions) and even “fileMode null” in the task and it makes no difference since it is using this static final variable. This has to be a bug, especially since there really isn’t a workaround except to change ownership to myself as root.

I’m aware I could just delete all the files and then recopy, which would give myself ownership but this seems to run counter to the whole idea of the Sync task.

This seems like a pretty fundamental problem with the copy/sync task. Can someone acknowledge this issue or explain why it is working as designed?

I think this is probably a bug, but I’m curious how your permission arrangement is supposed to work. Is the assumption that the files always exist before running this task? If one of them didn’t, and you did not have write access to the directory, then it would fail. If you did have write access to the directory, then it would succeed, but the new file would be owned by you (which it sounds like this is not what you want). This would apply not only to a fresh directory, but also to any new files that were added to the set of files being copied/synced.

Point is, even if gradle did handle this case, I’m wondering if what you are trying to do is going to work the way you want it to anyways. At least for a sync, Gradle assumes that it has control over the destination, otherwise it would only work under very specific circumstances (i.e. it would only work like a copy). Or maybe I just don’t fully grasp what you are trying to achieve…

Thanks for responding! Our use case is this:

We have a shared directory where anyone in the development group can deploy to and all files are mode 664. We are all in the same UNIX group, but the files will be owned by the first person to create them. The directory is group writable as well.

The key here is that the Gradle copy is functioning fine, it is the unnecessary chmod to 644 immediately afterwards that is failing even though I’ve set fileMode 664 in the gradle task (or even fileMode null which should leave it alone). UNIX allows anyone in the group to do anything to the files except chmod them.

To reproduce, just try doing a Gradle sync to a directory where you don’t own the files, but are a member of a group that is allowed to write to them. The directory is group writable as well, but UNIX won’t let you chmod something you don’t own.

OK, that makes sense. Wasn’t sure if the mixed ownership was desirable to you or not. I’ve opened an issue for this. We should probably just have a way to indicate that you want to disable the chmod when a file already exists.

1 Like

Thanks so much. I’ll keep my eye out for a fix and work around it until then.

You also run into this if you are attempting to write to a directory that is actually a mount to a windows machine, wherein the files will be owned as is set in fstab.

I haven’t been able to figure out a way to keep it from attempting the chmod operation.