【发布时间】:2018-10-07 19:47:19
【问题描述】:
背景
我继承了一个旧的、极其复杂的基于 Gradle 的 Java 项目,其中包含许多子项目。其中许多具有闭源 *.jar 库,这些库不应泄漏到其他(子)项目,以避免在多个项目使用不同版本的“相同”库时发生命名空间冲突。
我正在尝试更新项目以使用其中一些库的一些新版本,并通常清理依赖项,因为开发变得非常复杂。 更糟糕的是,一个项目嵌套为 Git submodule,它应该能够独立构建或作为我正在使用的主要 Gradle 项目的子项目。
Git 子模块
这是一个类似于 Git 子模块/Gradle 项目/Gradle 子项目的简化结构:
robotcontroller
+--.git
+--gradle
+--libs
+--planning
| +--src
| +--build.gradle
+--plugins
| +--nao
| | +--libs
| | | +--robocommons.jar
| | +--src
| | +--build.gradle
| +--pepper
| | +--libs
| | | +--graphadapter.jar
| | +--src
| | +--build.gradle
+--build.gradle
+--gradlew
+--gradlew.bat
+--settings.gradle
plugins/nao/build.gradle:
dependencies {
compile project(':planning')
// This is inside the subproject's "libs/" dir
compile name: 'robocommons'
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3'
}
[rootProject, this].each {
it.repositories {
flatDir {
dirs "${rootDir}/plugins/nao/libs/"
}
}
}
plugins/pepper/build.gradle:
dependencies {
compile project(':planning')
// This is inside the subproject's "libs/" dir
compile name: 'graphadapter'
compile group: 'com.google.guava', name: 'guava', version: '19.0'
}
[rootProject, this].each {
it.repositories {
maven {
// Some proprietary, closed-source repo
}
flatDir {
dirs "${rootDir}/plugins/pepper/libs/"
}
}
}
plugins/build.gradle:
dependencies {
compile project(':plugins:nao')
compile project(':plugins:pepper')
}
build.gradle:
// Stuff like plugins here
...
allprojects {
repositories {
flatDir {
dirs "${rootDir}/libs"
}
jcenter()
maven {
// Some other proprietary repo here
}
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
}
dependencies {
compile subprojects
}
// Stuff like javadoc and sourceJar tasks
...
settings.gradle:
include 'planning'
include 'plugins'
include 'plugins:nao'
include 'plugins:pepper'
“根”Git 存储库
上述Gradle项目及其所有子项目不仅需要能够独立构建,而且该项目本身就是另一个Gradle项目的子项目,该项目位于不同的Git存储库中:
complicatedrobotproject
+--.git
+--gradle
+--robotcontroller@SOMEREVISION // This is managed by the ".gitmodules" file
+--robocommons // A different, partially-compatible version of the source code used to make "robocommons.jar" is here
| +--src
| +--build.gradle
+--.gitmodules
+--build.gradle
+--gradlew
+--gradlew.bat
+--settings.gradle
build.gradle:
allprojects {
repositories {
flatDir {
dirs "${rootDir}/robotcontroller/libs"
}
}
}
dependencies {
// some external dependencies
...
compile project(":robotcontroller")
compile project(":robocommons")
// TEST
testCompile group: 'junit', name: 'junit', version: '4.12'
}
settings.gradle:
include 'robocommons'
include 'robotcontroller:planning'
include 'robotcontroller:plugins'
include 'robotcontroller:plugins:nao'
include 'robotcontroller:plugins:pepper'
问题
在上面的示例中,我的直接目标是将在complicatedrobotproject/robocommons 找到的源代码替换为robocommons.jar。但是,构建项目的唯一方法是使用 Git 子模块 robotcontroller 的修改版本,这实际上取决于它:
robotcontroller/plugins/nao/build.gradle 来自修订版SOMEREVISION:
dependencies {
compile name ':robocommons' // When building "complicatedrobotproject", this in fact links "robocommons" the directory, not "robocommons.jar"!
compile project(':robotcontroller:planning')
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3'
}
通过将:robotcontroller添加到依赖项中,可以构建项目complicatedrobotproject,但不能将robotcontroller构建为独立的Gradle项目。然后,采用该限定符可以使后者以牺牲前者为代价来构建。 robocommons.jar 中存在的类也存在于目录robocommons 中,它们在很大程度上但不完全等价。最终,我想将 both 替换为适当的外部依赖项,例如compile group: 'com.complicatedrobots', name: 'robocommons', version: '2.0.3',但这需要大量的重新实现,我首先需要理清这个依赖噩梦。
我的任务不是让项目有意义;尽管这让我很头疼,但我只需要两个 Git 存储库都是可构建的,并且在所有 Gradle 项目中使用单个版本的 robocommons,无论正在构建哪个 Git 存储库。我什至无法直截了当地思考这个问题,因为我想到的每一种可能性都会阻碍其他需要解决的问题。
【问题讨论】:
标签: java gradle dependencies build.gradle legacy