Как в Gradle объявить общие зависимости в одном месте?

109

В Maven есть очень полезная функция, когда вы можете определить зависимость в <dependencyManagement> разделе родительского POM и ссылаться на эту зависимость из дочерних модулей без указания версии или области действия или чего-то еще.

Какие есть альтернативы в Gradle?

Станислав Башкирцев
источник

Ответы:

179

Вы можете объявить общие зависимости в родительском скрипте:

ext.libraries = [ // Groovy map literal
    spring_core: "org.springframework:spring-core:3.1",
    junit: "junit:junit:4.10"
]

Затем из дочернего сценария вы можете использовать такие объявления зависимостей:

dependencies {
    compile libraries.spring_core
    testCompile libraries.junit
}

Чтобы поделиться объявлениями зависимостей с расширенными параметрами конфигурации, вы можете использовать DependencyHandler.create:

libraries = [
    spring_core: dependencies.create("org.springframework:spring-core:3.1") {
        exclude module: "commons-logging"
        force = true
    }
]

Под одним именем можно использовать несколько зависимостей:

libraries = [
    spring: [ // Groovy list literal
        "org.springframework:spring-core:3.1", 
        "org.springframework:spring-jdbc:3.1"
    ]
]

dependencies { compile libraries.spring } затем добавит обе зависимости сразу.

Единственная информация, которой вы не можете поделиться таким образом, - это какая конфигурация ( область действия в терминах Maven) должна быть назначена зависимости. Однако, по моему опыту, в любом случае лучше сказать об этом прямо.

Питер Нидервизер
источник
3
Спасибо, это решает мой вопрос, но все же вызывает беспокойство ... В Maven мы можем оставить версию пустой, и если это библиотека, это удобно, потому что вы можете использовать ее в нашем приложении и сделать dependencyManagement, чтобы определить, какая версия библиотеки это должно занять. Как бы вы сделали то же самое с Gradle?
Станислав Башкирцев 05.03.2012
Я не понимаю вопроса. Приведите пример.
Peter Niederwieser
4
Питер, ctapobep говорит, что в maven вы можете объявлять зависимости с версией (и областью действия) в родительском (или агрегатном) pom в разделе dependencyManagement. Тогда в "конкретном" помпе вам не нужно повторно объявлять версию; просто артефакт и groupId. По сути, он сообщает maven: «Мне нужен X: Y, но используйте ту версию, которую настроил родитель».
Майкл Кэмпбелл
2
Для того, чтобы избежать такого рода дублирования, я , как правило , чтобы создать отдельный dependencies.gradleсценарий , где я определяю всю мою зависимость как свойства, например: ext.GROOVY = 'org.codehaus.groovy:groovy-all:2.1.6'. В корневой проект build.gradleвключаю allprojects { apply from: "$rootDir/dependencies.gradle" }. Затем все зависимости определяются в одном файле вместо того, чтобы распространять их по всему миру, и в конфигурациях зависимостей используются более «легкие для чтения» константы.
Steinar
1
Это именно то, что я сделал выше. Вам не нужно подавать заявку, allprojectsпотому что дополнительные свойства уровня проекта видны подпроектам.
Питер Нидервизер
7

Это поздний ответ, но вы также можете взглянуть на: http://plugins.gradle.org/plugin/io.spring.dependency-management Он предоставляет возможность импортировать maven 'bom' и повторно использовать определения определено в "бомбе". Это, безусловно, хорошая помощь при постепенном переходе с maven на gradle! Наслаждаюсь этим прямо сейчас.

комнатыg
источник
это даже необходимо, если вы хотите использовать одни и те же зависимости в нескольких (мульти) проектах.
roomg
7
Хотя этот плагин удобен, он может иметь значительное влияние на производительность. Для 30 подпроектов с 200+ зависимостями это добавляет до 1 минуты к фазе разрешения зависимостей. Однако для небольших проектов это работает как шарм
Jk1 06
он также переопределяет переходные версии зависимостей, скажем, вы объявили версию 3.0.0 в управлении зависимостями, но для одного из подпроектов вам необходимо использовать более старую версию, например 2.5.0, тогда, если у вас есть проект, зависящий от этого более старого проекта, транзитивная зависимость будет перезаписана с 2.5.0 на то, что объявлено в плагине управления зависимостями, поэтому 3.0.0 в этом случае будет очень странным поведением
KameeCoding
7

Начиная с Gradle 4.6, ограничения зависимости предлагаются в документации как способ достижения этого. Из https://docs.gradle.org/current/userguide/declaring_dependencies.html#declaring_a_dependency_without_version :

Рекомендуемая практика для больших проектов - объявлять зависимости без версий и использовать ограничения зависимостей для объявления версии. Преимущество состоит в том, что ограничения зависимостей позволяют управлять версиями всех зависимостей, включая транзитивные, в одном месте.

В родительском build.gradleфайле:

allprojects {
  plugins.withType(JavaPlugin).whenPluginAdded {
    dependencies {
      constraints {
        implementation("com.google.guava:guava:27.0.1-jre")
      }
    }
  }
}

Оборачивание блока зависимостей проверкой плагина Java (... whenPluginAdded {) не является строго необходимым, но затем он будет обрабатывать добавление проекта, отличного от Java, в ту же сборку.

Затем в дочернем проекте Gradle вы можете просто опустить версию:

apply plugin: "java"

dependencies {
  implementation("com.google.guava:guava")
}

В дочерних сборках по-прежнему можно указать более высокую версию. Если указана более низкая версия, она автоматически обновляется до версии в ограничении.

Адриан Бейкер
источник
1
Ограничения зависимости были добавлены в Gralde 4.6, поэтому это будет работать с Gradle 4.6 или выше.
Джим Хёрн,
Я думаю, что Gradle предусматривает использование подключаемого модуля платформы Java в таком случае. Однако документация Gradle на данный момент не очень ясна. Думаю, использование allprojectsтоже нормально.
JojOatXGME
Я хочу объявить ограничения в корневом проекте, но только в одном из моих подпроектов, я хочу загрузить все те зависимости, для которых определены ограничения.
dtc
2

io.spring.gradle:dependency-management-pluginплагин имеет проблемы с новой серией Gradle 3.x, но стабилен для серии 2.x. Для справки см. Отчет об ошибке Drop support for Gradle 3 # 115

В случае Spring ( основной промоутер использования BOM ) вы можете закончить:

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }
    dependencies {
        classpath 'io.spring.gradle:dependency-management-plugin:1.0.0.RELEASE'
    }
}

repositories {
    mavenLocal()
    jcenter()
}

apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'

dependencyManagement {
    imports {
        mavenBom 'io.spring.platform:platform-bom:Athens-SR3'
    }
}

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'

    testCompile 'org.springframework.boot:spring-boot-starter-test'
}

Обратите внимание, что io.spring.platform:platform-bomесть org.springframework.boot:spring-boot-starter-parentродительский элемент, поэтому он совместим с Spring Boot

Вы можете проверить фактическое разрешение зависимостей с помощью:

$ gradle dependencies
$ gradle dependencies --configuration compile
$ gradle dependencies -p $SUBPROJ

$ gradle buildEnvironment
$ gradle buildEnvironment -p $SUBPROJ

или с задачей:

task showMeCache {
    configurations.compile.each { println it }
}

Прочтите официальный пост в блоге Soring. Лучшее управление зависимостями для Gradle, чтобы понять причину внедрения io.spring.gradle:dependency-management-plugin.

гавенкоа
источник
1

Вы можете централизовать зависимость, используя приведенный ниже код:

В gradle.properties

COMPILE_SDK_VERSION=26
BUILD_TOOLS_VERSION=26.0.1
TARGET_SDK_VERSION=26
MIN_SDK_VERSION=14

ANDROID_SUPPORT_VERSION=26.0.2

В каждый модуль добавить build.gradle:

android {
    compileSdkVersion COMPILE_SDK_VERSION as int
    buildToolsVersion BUILD_TOOLS_VERSION as String

    defaultConfig {
        minSdkVersion MIN_SDK_VERSION as int
        targetSdkVersion TARGET_SDK_VERSION as int
        versionCode 1
        versionName "1.0"

    }

}

dependencies {
 compile "com.android.support:appcompat-v7:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:support-v4:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:support-annotations:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:support-vector-drawable:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:design:${ANDROID_SUPPORT_VERSION}"
}
Дхавал Дживани
источник
1

В этом сообщении блога предлагается управлять зависимостями и группами как конфигурациями: https://www.javacodegeeks.com/2016/05/manage-dependencies-gradle-multi-project-build.html

Сам не пробовал, но смотрится интересно.

Корневой проект build.gradle

subprojects {
  configurations {
    commonsIo
  }

  dependencies {
    commonsIo 'commons-io:commons-io:2.5'
  }
}

Подпроект build.gradle

configurations {
  compile.extendsFrom commonsIo
}
ткрузе
источник
0

Чтобы ваш файл gradle был чистым, мы можем сгруппировать зависимости в массив и реализовать их позже.

  1. Добавьте такую ​​версию библиотек в build.gradle (уровень приложения) вне блока зависимостей :

// объявляем версии библиотеки

final RetrofitVersion = '2.3.0'
final OkHttpVersion = '3.9.1'
  1. Создайте массив связанных зависимостей, чтобы вы могли легко найти его позже. Добавьте его в build.gradle (уровень приложения) вне блока зависимостей :

// Использование версии в библиотеке и добавление зависимости вместе с именем доступа (например, модернизация (первая))

final networkDependencies = [
        retrofit             : "com.squareup.retrofit2:retrofit:${RetrofitVersion}",
        retrofitGsonConverter: "com.squareup.retrofit2:converter-gson:${RetrofitVersion}",
        retrofitRxJavaAdapter: "com.squareup.retrofit2:adapter-rxjava2:${RetrofitVersion}",
        okHttp3              : "com.squareup.okhttp3:okhttp:${OkHttpVersion}",
        okHttp3Logging       : "com.squareup.okhttp3:logging-interceptor:${OkHttpVersion}"
]
  1. И в блоке зависимостей :

// Реализуем все зависимости от массива

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation networkDependencies.values()
}

Таким образом, окончательный код будет выглядеть следующим образом :

final RetrofitVersion = '2.3.0'
final OkHttpVersion = '3.9.1'

final networkDependencies = [
        retrofit             : "com.squareup.retrofit2:retrofit:${RetrofitVersion}",
        retrofitGsonConverter: "com.squareup.retrofit2:converter-gson:${RetrofitVersion}",
        retrofitRxJavaAdapter: "com.squareup.retrofit2:adapter-rxjava2:${RetrofitVersion}",
        okHttp3              : "com.squareup.okhttp3:okhttp:${OkHttpVersion}",
        okHttp3Logging       : "com.squareup.okhttp3:logging-interceptor:${OkHttpVersion}"
]

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation networkDependencies.values()
}
Сурадж Вайшнав
источник
как включить этим обработчик аннотаций ?? как в случае с ломбоком
Притиш Джоши