当目标目录的文件/目录具有提升的访问权限时,为什么Gradle“复制”任务失败?

时间:2019-04-04 14:30:38

标签: gradle

在使用Gradle复制任务将人工制品复制到包含其他文件和/或目录的目录中,这些文件和/或目录具有当前用户权限之外的访问权限,则gradle任务将失败。似乎Gradle试图枚举目标目录的内容,并且当它遇到无法读取的文件/目录时,它将失败。我有一种预感,最新的检查会尝试对内容进行哈希处理,并且在无法读取目标目录中的文件/目录时会失败。我的理解正确吗?我该如何解决?是否可以仅禁用复制任务的最新检查?

环境

我在Ubuntu 18.04上使用Gradle 4.8.1。

背景故事

我在进行Udemy gradle课程时遇到了这个挑战/问题。讲座特别涉及使用“复制”任务将War文件部署到Tomcat webapps目录。我懒得安装Tomcat堆栈,所以我启动了一个docker映像,其挂载从我的主机映射到容器内的webapps目录。

docker容器以root用户身份运行Tomcat进程,并按预期的第一次部署我的战争。最终的解压缩目录归root:root所有。

重新运行gradle构建脚本以重新部署新的/相同(无关紧要/无关紧要的)war文件时,它会失败。这只是导致我进入这里的背景。请注意,我不是在寻找设置Tomcat或使用Docker的更好方法。我的实验/测试从经验上将Tomcat和Docker从方程式中分离出来。

与我的错误相关的所有其他SO问题似乎与MS Windows /防病毒相关。我没有使用Windows,也没有安装防病毒软件。

我的gradle.build文件

plugins {
  id 'java'
  id 'war'
}

group = 'com.denofprogramming'
version = '0.0.1-SNAPSHOT'

sourceCompatibility = 1.8
targetCompatibility = 1.8

ext.tomcatWebapps = "/home/donovanh/fake/"

repositories{
    mavenCentral()
}

dependencies { 
    implementation 'org.springframework:spring-webmvc:4.0.3.RELEASE'
    implementation 'javax.inject:javax.inject:1'
    implementation 'org.apache.commons:commons-math3:3.2'
    implementation 'jstl:jstl:1.2'
    implementation 'log4j:log4j:1.2.17'
    compileOnly "javax.servlet:javax.servlet-api:3.0.1"
    testImplementation  'junit:junit:4.11'
}

war {
    archiveName = 'mywebappInitial.war'
}

task deployToWebserver(type: Copy, dependsOn: 'war') {
    from war.archivePath
    into "$tomcatWebapps"
}

重要的部分是(有问题的任务):

task deployToWebserver(type: Copy, dependsOn: 'war') {
    from war.archivePath
    into "$tomcatWebapps"
}

观察

Gradle构建在Eclipse和命令行中均失败。 共有三种情况:

方案1 :目标目录不包含具有升级权限的文件/目录时。任务成功

在这种情况下,目标目录可以包含其他文件和目录,只要它们不受运行Gradle构建的用户的访问限制即可,例如root:root所拥有的文件都没有。

方案2 :目标目录包含具有升级权限的文件时。任务失败:

创建具有升级权限的名为a的文件:

$ touch a
$ sudo chown root:root a
$ sudo chmod 740 a
$ ls -ltra
total 24
drwxr-xr-x 88 donovanh donovanh 20480 Apr  4 00:36 ..
-rwxr-----  1 root     root         0 Apr  4 01:21 a
drwxrwxr-x  2 donovanh donovanh  4096 Apr  4 01:21 .

运行gradle任务:

> Task :deployToWebserver FAILED
:deployToWebserver (Thread[Task worker for ':',5,main]) completed. Took 0.021 secs.

FAILURE: Build failed with an exception.

* What went wrong:
Failed to capture snapshot of output files for task ':deployToWebserver' property 'destinationDir' during up-to-date check.
> Failed to create MD5 hash for file '/home/donovanh/fake/a' as it does not exist.

与错误相反,文件a确实存在,但是具有以下权限:

-rwxr-----  1 root     root         0 Apr  4 01:21 a

方案3 :目标目录包含具有升级权限的目录时。任务失败:

创建具有升级特权的名为a的目录:

$ mkdir a 
$ sudo chmod 740 a
$ sudo chown root:root a

运行gradle任务:

> Task :deployToWebserver FAILED
:deployToWebserver (Thread[Task worker for ':',5,main]) completed. Took 0.02 secs.

FAILURE: Build failed with an exception.

* What went wrong:
Failed to capture snapshot of output files for task ':deployToWebserver' property 'destinationDir' during up-to-date check.
> Could not read path '/home/donovanh/fake/a'.

我注意到目录和文件方案具有不同的错误消息-因此使它们成为两个单独的方案。我假设最新的检查程序正在尝试枚举目标目录以创建内容的哈希。当遇到无法访问的文件或目录时,它将失败。

我也尝试过使用outputs.upToDateWhen { true } 并输出.upToDateWhen {false}

按照:

task deployToWebserver(type: Copy, dependsOn: 'war') {
    outputs.upToDateWhen { true/false }
    from war.archivePath
    into "$tomcatWebapps"
}

...无济于事。

问题

如何将文件复制到包含其他不可访问的文件和/或目录的目录中?

0 个答案:

没有答案