[英]Dependencies relative to Gradle subprojects which are also buildable independently
I've inherited an old, extremely complicated Gradle-based Java project with many sub-projects. 我继承了一个古老的,极其复杂的基于Gradle的Java项目,其中包含许多子项目。 Many of these have closed-source *.jar
libraries that should not leak to other (sub-)projects in order to avoid namespace clashes when multiple projects use different versions of the "same" library. 其中许多具有闭源*.jar
库,这些库不应泄漏给其他(子)项目,以避免当多个项目使用不同版本的“相同”库时发生命名空间冲突。
I'm trying to update the project to use some new versions of some of these libraries and in general clean up the dependencies, since development has become extremely complicated. 我正在尝试更新项目,以使用其中某些库的某些新版本,并通常清理依赖项,因为开发变得极为复杂。 To make things worse, one project is nested as a Git submodule , which is supposed to be able to be built either independently or as a subproject of the main Gradle project I'm working with. 更糟糕的是,有一个项目是嵌套的Git的子模块 ,它应该是能够独立或作为主要项目摇篮我工作的一个子项目,待建。
Here is a simplified structure analogous to the Git submodule/Gradle project/Gradle sub-project: 这是类似于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
: 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
: 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
: plugins/build.gradle
:
dependencies {
compile project(':plugins:nao')
compile project(':plugins:pepper')
}
build.gradle
: 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
: settings.gradle
:
include 'planning'
include 'plugins'
include 'plugins:nao'
include 'plugins:pepper'
The Gradle project and all of its sub-projects above not only need to be able to be built on their own, but the project is itself a sub-project of another Gradle project, which is in a different Git repository: 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
: 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
: settings.gradle
:
include 'robocommons'
include 'robotcontroller:planning'
include 'robotcontroller:plugins'
include 'robotcontroller:plugins:nao'
include 'robotcontroller:plugins:pepper'
In the example above, my immediate goal is to replace the source code found at complicatedrobotproject/robocommons
with robocommons.jar
. 在上面的示例中,我的近期目标是用robocommons.jar
替换在complicatedrobotproject/robocommons
找到的源代码。 However, the only way to build the project is with a modified version of the Git submodule robotcontroller
that actually depends on that: 但是,构建项目的唯一方法是使用Git子模块robotcontroller
的修改版本,该版本实际上取决于该版本:
robotcontroller/plugins/nao/build.gradle
from revision SOMEREVISION
: 修订版SOMEREVISION
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'
}
By adding :robotcontroller
to the dependencies, the project complicatedrobotproject
can be built, but robotcontroller
cannot be built as a standalone Gradle project. 通过将:robotcontroller
添加到依赖项中,可以构建complicatedrobotproject
:robotcontroller
项目,但不能将robotcontroller
构建为独立的Gradle项目。 Taking that qualifier then makes the latter buildable at the expense of the former. 然后,采用该限定符可以使后者可构建,但要牺牲前者。 The classes present in robocommons.jar
that are also present in the directory robocommons
are largely but not completely equivalent. 存在于类robocommons.jar
是也出现在目录robocommons
很大程度上但不完全等同。 Ultimately, I want to replace both with a proper external dependency to eg compile group: 'com.complicatedrobots', name: 'robocommons', version: '2.0.3'
, but that will require a lot of re-implementation, and I first need to sort out this dependency nightmare. 最终,我想用适当的外部依赖项来替换两者 ,例如compile group: 'com.complicatedrobots', name: 'robocommons', version: '2.0.3'
,但这将需要大量重新实现,而我首先需要解决这种依赖的噩梦。
My task is not to make the project make sense; 我的任务不是使项目有意义。 As much as this makes my head hurt, I just need both Git repositories to be buildable and also using a single version of robocommons
across all Gradle projects, regardless of which Git repository is being built. 尽管这让我很robocommons
,但我只需要既可以构建Git仓库,又可以在所有Gradle项目中使用单个版本的robocommons
,无论构建哪个Git仓库。 I can't even think about the problem straight because every single possibility I think of blocks out some other thing that needs to work. 我什至无法直接考虑问题,因为我想到的每一种可能性都会阻止其他需要解决的问题。
I can't say I understand what's happening in that build and I feel your pain. 我不能说我了解该构建中正在发生的事情,并且我感到您的痛苦。 The first thing I would say is that composite builds may offer a pathway to a "normal", maintainable build, allowing you to keep robotcontroller as a separate project. 我要说的第一件事是, 复合构建可能会提供通往“正常”,可维护构建的途径,从而使您可以将robotcontroller保留为单独的项目。 If you go down this route, you will have to remove the `include ":robotcontroller" from the parent's settings.gradle file and replace it with the equivalent composite build configuration. 如果沿这条路线走,则必须从父级的settings.gradle文件中删除`include“:robotcontroller”并将其替换为等效的复合构建配置。
That said, I think you can get this working fairly easily, because most of the pieces appear to be in place. 就是说,我认为您可以很轻松地完成此工作,因为大部分内容似乎都已准备就绪。 I would do this: 我会这样做:
Move all of those JARs currently in plugins/*/libs into robotcontroller/libs , adding a version to their file names 将当前在plugins / * / libs中的所有这些JAR移至robotcontroller / libs中 ,在其文件名中添加一个版本
Update all the dependencies on those JARs so that they include the appropriate version 更新这些JAR上的所有依赖项,以便它们包含适当的版本
Remove the /robocommons directory 删除/ robocommons目录
You see, robotcontroller/libs appears to already be set up as a flat directory repository in both robotcontroller and the parent project. 您会看到, robotcontroller / libs似乎已经在robotcontroller和父项目中都设置为平面目录存储库。 It seems to me that the only reason the problematic libraries are in project-specific directories is because they don't have version numbers in their names to distinguish them. 在我看来,有问题的库位于特定于项目的目录中的唯一原因是因为它们的名称中没有版本号来区分它们。 By adding the version number, you can keep them side by side in the same directory. 通过添加版本号,您可以将它们并排放置在同一目录中。
Does that make sense? 那有意义吗? Hope it helps anyway! 希望无论如何能有所帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.