“刷新所有gradle项目”给出了以下错误:
Error:(15, 0) Cannot change dependencies of configuration ':util:compile' after it has been included in dependency resolution.
当我将第二个if语句移动到子模块项目的build.gradle时,不会发生此问题。虽然我找到了解决方法,但我想了解为什么原始解决方案不正确。制造麻烦的路线是:
"Class-Path": (configurations.compile.collect {"$dependencyDir/$it.name"}.join(" "))
项目结构:
mcv-gradle-example
|__ submodule (gradle project)
|__ util (gradle project)
|__ build.gradle
的build.gradle:
allprojects {
apply plugin: 'java'
}
subprojects {
apply plugin: 'scala'
repositories {
mavenCentral()
}
def isSpecialProject = project.name in ["submodule"]
dependencies {
compile group: 'org.scala-lang', name: 'scala-library', version: '2.12.1'
if (isSpecialProject) {
compile project(':util')
}
}
if (isSpecialProject) {
def dependencyDir = "/deps"
task setupJarManifest() {
jar.manifest.attributes(
"Class-Path": (configurations.compile.collect {"$dependencyDir/$it.name"}.join(" ")))
}
jar.dependsOn setupJarManifest
}
}
更新
我发现拥抱jar.manifest...
和afterEvaluate
允许在main build.gradle中执行此任务。但是我仍然不确定gradle的问题是什么。
更新2: 似乎移动设置manifest.attributes到执行阶段解决了他的问题。我的最终解决方案是:
if (isSpecialProject) {
def dependencyDir = "deps"
jar {
doFirst {
manifest.attributes(
"Class-Path": (configurations.compile.collect {"$dependencyDir/$it.name"}.join(" "))
)
}
}
}
我的猜测是:
当子模块项目在配置阶段使用configurations.compile
时,将解决所有依赖项。然后针对util项目评估子项目闭包。由于util是子模块的依赖,因此在不久前我们使用了它的所有依赖关系。这是合理的,但我仍然不知道configurations.compile的用法如何将util的依赖关系标记为已关闭。
解释
经过一些研究后,我终于知道发生了什么:
submodule
。它将scala和子项目util
放入其依赖项中。 configurations.compile.collect
内部调用iterator
方法调用DefaultConfiguration#getFiles
。要查找为此配置指定的文件,它会解析图形和工件(锁定它的依赖项修改功能)。util
评估子项目闭包。它试图将scala放在其依赖项中但由于第2点而被锁定,因此它会抛出错误。在正确解析图形和工件后,将collect
移动到afterEvaluation
或doLast
会执行它。它可以在执行阶段多次调用。