Фон
Я унаследовал старый, чрезвычайно сложный Java-проект на основе Gradle со многими подпроектами. Многие из них имеют *.jar
библиотеки с закрытым исходным кодом, которые не должны попадать в другие (под) проекты, чтобы избежать конфликтов пространства имен, когда несколько проектов используют разные версии "одной и той же" библиотеки.
Я пытаюсь обновить проект для использования некоторых новых версий некоторых из этих библиотек и в целом очистить зависимости, так как разработка стала чрезвычайно сложной.
Что еще хуже, один проект вложен как подмодуль Git , который, как предполагается, может быть построен независимо или как подпроект основного проекта 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
, в значительной степени, но не полностью эквивалентны. В конечном счете, я хочу заменить обоих на соответствующую внешнюю зависимость, например, compile group: 'com.complicatedrobots', name: 'robocommons', version: '2.0.3'
, но это потребует много повторной реализации, и сначала мне нужно разобраться с этим кошмаром зависимости.
Моя задача - не придавать проекту смысл; Как бы это ни причиняло мне боль, мне нужно, чтобы оба репозитория Git были доступны для сборки, а также использовать одну версию robocommons
для всех проектов Gradle, независимо от того, какой репозиторий Git создается. Я даже не могу думать о проблеме прямо, потому что каждая возможность, о которой я думаю, блокирует какую-то другую вещь, которая должна работать.