Какие подводные камни и конфликты могут возникнуть при объединении двух Android проектов с помощью composite builds в Gradle
Что проверяют
Понимаете ли вы, что includeBuild склеивает не модули, а две самостоятельные сборки, и что подмена зависимостей работает по координатам. Следом обычно спрашивают, чем composite build отличается от многомодульного проекта и от публикации библиотеки в mavenLocal.
Как отвечать
Composite build подключается в settings.gradle.kts через includeBuild("../core-lib"). Включённая сборка остаётся отдельной, со своими settings и плагинами. Gradle подменяет внешнюю зависимость com.example:core на проект из неё, если совпадают group и имя модуля. Отсюда проблемы:
- подмена молча меняет версию: приложение просило
core:1.4.0, а получает текущий исходник из соседней папки. Её транзитивные зависимости попадают в общее разрешение, и OkHttp или корутины могут неожиданно обновиться до старшей версии; - координаты не совпали: если
groupу библиотеки другой, подмены не будет, Gradle пойдёт в репозиторий. Выручает явныйdependencySubstitution; - варианты сборки: у приложения есть
stagingили flavor, которых нет в библиотеке, и сборка падает на выборе варианта. ЛечитсяmatchingFallbacks, а обратный случай закрываетmissingDimensionStrategy; - расхождение плагинов и SDK: разные версии AGP и Kotlin,
compileSdk, JDK toolchain. Более высокийminSdkу библиотеки роняет слияние манифестов; - version catalog не общий:
libs.versions.tomlкорня включённая сборка не видит, его подключают в еёsettingsотдельно; - дубли: одинаковый
namespaceили один модуль в обоих проектах даютDuplicate classи тихое перекрытие ресурсов; - задачи:
./gradlew testв корне не запускает тесты включённой сборки, связь прописывают черезgradle.includedBuild(...).
Где спотыкаются
Путают composite build с include(":module") и ждут, что настройки корня применятся ко всему.
Советуют --configure-on-demand для ускорения. Это инкубационный режим, с которым Android исторически не дружит; выигрыш дают configuration cache и build cache.
Считают, что dependencyResolutionManagement решает конфликты версий. Он централизует репозитории и каталоги версий, а конфликты решают constraints и resolutionStrategy.