Як у 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 ми можемо залишити версію порожньою, і якщо це lib, це зручно, тому що ви можете використовувати її в нашому додатку і зробити залежностіManagement, щоб визначити, яку версію lib це повинно пройти. Як би ви зробили те саме з Gradle?
Станіслав Башкирцев

Я не розумію питання. Наведіть приклад.
Пітер Нідервізер

4
Петре, що говорить ctapobep - це те, що в maven ви можете оголосити залежності з версією (і обсягом) у батьківському (або агрегаторі) пом’ї в розділі залежностіManagement. Тоді в "конкретному" пом, вам не потрібно повторно оголошувати версію; просто артефакт та групаId. В основному він говорить Maven "Мені потрібно X: Y, але використовувати будь-яку версію, яку налаштував батьків".
Майкл Кемпбелл

2
Для того, щоб уникнути такого роду дублювання, я , як правило , щоб створити окремий dependencies.gradleсценарій , де я визначаю всю мою залежність як властивості, наприклад: ext.GROOVY = 'org.codehaus.groovy:groovy-all:2.1.6'. У корінний проект build.gradleя включаю allprojects { apply from: "$rootDir/dependencies.gradle" }. Тоді всі залежності визначаються в одному файлі замість того, щоб поширювати їх навколо, а в конфігураціях залежностей використовуються більш "легкі для читання" константи.
Стейнар

1
Саме це я і робив вище. Не потрібно звертатися до цього, allprojectsоскільки додаткові властивості на рівні проекту видно підпроектам.
Пітер Нідервайзер

7

Це пізня відповідь, але ви, можливо, також захочете ознайомитись з цим: http://plugins.gradle.org/plugin/io.spring.dependency-management Це надає можливість імпортувати Maven 'bom' та повторно використовувати визначення. визначені в "бомі". Це, безумовно, приємна допомога при поступовому переході від Maven до gradle! Насолоджуйтесь ним прямо зараз.


це навіть обов'язково, коли ви хочете поділити однакові залежності у кількох (кількох) проектах.
roomg

7
Хоча це зручно, цей плагін може мати значний ефект роботи. Для 30 підпроектів із залежністю 200+ це додає до 1 хвилини фази вирішення залежності. Для невеликих проектів це працює як принадність
Jk1

він також перекриває версії транзитивних залежностей, скажімо, ви оголосили версію 3.0.0 в управлінні залежністю, але для одного з підпроектів потрібно використовувати старішу версію, наприклад, 2.5.0, то якщо у вас є проект, залежний від цього старого проекту, транзитивна залежність буде перезаписана з 2.5.0 на те, що заявлено в плагіні управління залежністю, тому 3.0.0 в цьому випадку дуже дивна поведінка
KameeCoding

7

Станом на Gradle 4.6 обмеження залежності пропонуються в документації як спосіб цього досягти. З https://docs.gradle.org/current/userguide/declaring_dependency.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 проекту до тієї ж збірки.

Тоді в проекті дочірнього градуса ви можете просто опустити вигляд:

apply plugin: "java"

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

Дочірні версії все ще можуть обрати більш високу версію. Якщо вказана нижча версія, вона автоматично буде оновлена ​​до версії з обмеженням.


1
В Gralde 4.6 були додані обмеження залежності, тому це буде працювати з Gradle 4.6 або вище.
Джим Хурн

Я думаю, що Gradle передбачає, що плагін Java Platform використовується в такому випадку. Однак документація на Gradle не дуже зрозуміла на даний момент. Я думаю, що використання allprojectsтакож добре.
JojOatXGME

Я хочу оголосити обмеження в кореневому проекті, але лише в одному з моїх підпроектів, я хочу завантажити всі ті залежності, які мають обмеження.
dtc

2

io.spring.gradle:dependency-management-pluginплагін має проблеми з новою серією Gradle 3.x, але стабільний для серії 2.x. Для ознайомлення подивіться звіт про помилки Підтримка підтримки для Gradle 3 # 115

У випадку весни ( головний промоутер використання 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 }
}

Прочитайте офіційне повідомлення про сортування в Сортування. Краще управління залежностями для 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-dependitions-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()
}

як включити процесор анотацій цим ?? як у випадку ломбока
Прітіш Джоші
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.