我在我的 mutliproject Gradle 构建中遇到了奇怪的行为。有问题的项目是开源的,所以欢迎那些想深入了解构建的人在这里查看,在分支开发上。
在父项目中,我定义了一个fatJar
任务如下:
task fatJar(type: Jar, dependsOn: subprojects.compileJava) {
manifest {
attributes 'Implementation-Title': 'Alchemist',
'Implementation-Version': rootProject.version,
'Main-Class': 'it.unibo.alchemist.Alchemist'
}
baseName = "${rootProject.name}-redist"
from(configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }) {
// remove all signature files
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
exclude 'build'
exclude '.gradle'
exclude 'build.gradle'
exclude 'gradle'
exclude 'gradlew'
exclude 'gradlew.bat'
}
with jar
}
生成失败的一个子项目有点特殊,因为它使用了 ANTLR(我省略了依赖项和其他我认为对理解手头问题没有必要的代码)。
apply plugin: 'antlr'
sourceSets {
antlr
}
generateGrammarSource {
arguments += ["-visitor", "-package", "it.unibo.alchemist.biochemistrydsl"]
def target = new File('src/antlr/java/')
if ((target.exists() && target.isDirectory()) || target.mkdirs()) {
outputDirectory = target
} else {
throw new IllegalStateException("$target is not an existing directory and could not be created as such.")
}
}
compileAntlrJava.dependsOn('generateGrammarSource')
compileJava.dependsOn('compileAntlrJava')
现在,./gradlew clean && ./gradlew fatJar
从父项目中运行时,我遇到了失败,但有以下异常(为简洁起见,省略了某些部分):
> Failed to create MD5 hash for file '[my project folder]/alchemist/alchemist-incarnation-biochemistry/build/classes/java/antlr' as it does not exist.
* Exception is:
org.gradle.api.UncheckedIOException: Failed to capture snapshot of input files for task ':fatJar' property 'rootSpec$1$1' during up-to-date check.
at org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository.snapshotTaskFiles(CacheBackedTaskHistoryRepository.java:331)
<snip>
Caused by: org.gradle.api.UncheckedIOException: Failed to create MD5 hash for file '[my project folder]/alchemist/alchemist-incarnation-biochemistry/build/classes/java/antlr' as it does not exist.
at org.gradle.internal.hash.DefaultFileHasher.hash(DefaultFileHasher.java:45)
<snip>
Caused by: java.io.FileNotFoundException: [my project folder]/alchemist/alchemist-incarnation-biochemistry/build/classes/java/antlr (Is a directory)
at org.gradle.internal.hash.DefaultFileHasher.hash(DefaultFileHasher.java:38)
系统抱怨为文件夹的文件实际上存在并且实际上是一个文件夹,但它应该确实存在。现在,让我感到困惑的是,如果./gradlew fatJar
第二次调用它,它就会成功完成。这可以在不同的系统上重现,不同的 Gradle 版本(保留在 4.x 版本上)和操作系统(Arch Linux 和 MacOS X)。