首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >相对于也可独立构建的Gradle子项目的依赖关系

相对于也可独立构建的Gradle子项目的依赖关系
EN

Stack Overflow用户
提问于 2018-04-27 02:29:59
回答 2查看 1.3K关注 0票数 0

背景

我继承了一个古老的、极其复杂的基于层次的Java项目,其中有许多子项目。其中许多具有不应该泄漏给其他(子)项目的封闭源*.jar库,以避免在多个项目使用“相同”库的不同版本时出现名称空间冲突。

我正在尝试更新这个项目,以使用其中一些库的一些新版本,并且通常清理依赖项,因为开发已经变得非常复杂。更糟糕的是,一个项目被嵌套为一个Git子模,它应该能够独立构建,作为我正在使用的主Gradle项目的一个子项目。

Git子模块

下面是一个类似于Git子模块/Gradle项目/Gradle子项目的简化结构:

代码语言:javascript
复制
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**:**

代码语言:javascript
复制
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**:**

代码语言:javascript
复制
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**:**

代码语言:javascript
复制
dependencies {
    compile project(':plugins:nao')
    compile project(':plugins:pepper')
}

build.gradle**:**

代码语言:javascript
复制
// 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**:**

代码语言:javascript
复制
include 'planning'
include 'plugins'
include 'plugins:nao'
include 'plugins:pepper'

根Git存储库

Gradle项目及其上面的所有子项目不仅需要能够自己构建,而且项目本身也是另一个Gradle项目的子项目,它位于一个不同的Git存储库中:

代码语言:javascript
复制
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**:**

代码语言:javascript
复制
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**:**

代码语言:javascript
复制
include 'robocommons'
include 'robotcontroller:planning'
include 'robotcontroller:plugins'
include 'robotcontroller:plugins:nao'
include 'robotcontroller:plugins:pepper'

问题

在上面的示例中,我的直接目标是用robocommons.jar替换在robocommons.jar中找到的源代码。但是,构建该项目的唯一方法是使用Git子模块robotcontroller的修改版本,该版本实际上依赖于此:

robotcontroller/plugins/nao/build.gradle 来自 SOMEREVISION**:**修订版

代码语言:javascript
复制
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中的类在很大程度上是完全等价的。最终,我想用一个适当的外部依赖(例如,)替换和,但是这需要大量的重新实现,我首先需要解决这个依赖噩梦。

我的任务不是让这个项目有意义;尽管这让我头疼,但我只需要两个Git存储库都是可构建的,并且需要在所有Gradle项目中使用单一版本的robocommons,而不管构建的是哪个Git存储库。我甚至不能直截了当地思考这个问题,因为我想出的每一种可能性都排除了一些需要解决的问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-27 07:25:48

我不能说我理解建筑里发生了什么,我感觉到了你的痛苦。我要说的第一件事是,复合构建可能提供一条通向“正常”、可维护的构建的途径,允许您将robotcontroller保持为一个单独的项目。如果您沿着这条路线走下去,您将不得不从父settings.gradle文件中删除‘`include“:robotcontroller,并将其替换为等效的复合构建配置。

尽管如此,我认为你可以很容易地让它工作起来,因为大部分的部分似乎已经到位了。我会这么做:

  1. 将当前在plugins/*/lib中的所有这些JAR移动到robotcontroller/lib中,在它们的文件名中添加一个版本
  2. 更新这些JAR上的所有依赖项,以便它们包含适当的版本。
  3. 删除/robocommons目录

您可以看到,robotcontroller/libs似乎已经被设置为robotcontroller和父项目中的一个平面目录存储库。在我看来,问题库出现在特定于项目的目录中的唯一原因是它们的名字中没有版本号来区分它们。通过添加版本号,您可以将它们并排放在同一个目录中。

这有意义吗?希望它能帮上忙!

票数 0
EN

Stack Overflow用户

发布于 2022-10-19 10:35:49

最近当我遇到一个类似的问题时,我偶然发现了这个问题。

并不是说我的解决方案在客观上更好,但我对Gradle (至少是v7,但可能是较低版本的b/c -对我来说搜索changelog太晚了),答案可能比上面的更容易解决。

以下任一项:

  1. 使用apply from: <my-personal>build.gradle,它将“注入”所有子依赖项+来自上述子项目的源代码。
  2. (最理想的)事实是,您说它是一个不同的存储库,这意味着您应该使用托管的注册中心,即微服务。从某种注册中心(意思是将其发布到某个地方,并将其安装在dependencies {}块中而不是其他任何地方)并以这种方式使用它。在我自己跳过一些循环之后,我发现这是一种更简单的方法来完成你想要的事情。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50054359

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档