Как мне остановить Gradle от обновления транзитивных зависимостей? - PullRequest
1 голос
/ 22 января 2020

Почему Gradle изменяет переходную зависимость моей библиотеки на более новую версию? Как мне остановить его?

Подробности

Я работаю над внутренней библиотекой плагинов для моей компании, которая использует Spring Security. Плагин явно объявляет зависимость от последней версии Spring Security 4:

    compile ('org.springframework.security:spring-security-core:4.2.13.RELEASE') {
        force = true
    }

Когда я включаю плагин в клиентский проект, Gradle переводит меня с весенней безопасности 4 на 5, что нарушает плагин.

    compile 'com.mycompany:my-security-plugin:0.3.0-SNAPSHOT'

Вот вывод файла dependencyInsight в клиентском проекте:

> Task :dependencyInsight
org.springframework.security:spring-security-core:5.1.6.RELEASE (selected by rule)
   variant "compile" [
      org.gradle.status             = release (not requested)
      org.gradle.usage              = java-api
      org.gradle.component.category = library (not requested)
   ]

org.springframework.security:spring-security-core:5.1.6.RELEASE
+--- org.springframework.security:spring-security-config:5.1.6.RELEASE
|    \--- com.mycompany:my-security-plugin:0.3.0-SNAPSHOT:20200122.162056-4 (requested org.springframework.security:spring-security-config:4.2.13.RELEASE)
|         \--- compileClasspath
\--- org.springframework.security:spring-security-web:5.1.6.RELEASE
     \--- com.mycompany:my-security-plugin:0.3.0-SNAPSHOT:20200122.162056-4 (requested org.springframework.security:spring-security-web:4.2.13.RELEASE) (*)

org.springframework.security:spring-security-core:4.2.13.RELEASE -> 5.1.6.RELEASE
\--- com.mycompany:my-security-plugin:0.3.0-SNAPSHOT:20200122.162056-4
     \--- compileClasspath

Мне кажется, что во всех случаях я запрашиваю Spring Security 4 в моей конфигурации. Что я делаю не так?

Я использую Gradle 5.1.1.

Обновление

В качестве обходного пути, возможно иметь клиента Приложение объявляет прямую зависимость от безопасности Spring, используя указанную c версию. Я пытаюсь избежать этого, если это возможно.

Обновление 2

Вывод из gradlew dependencyInsight --dependency org.springframework.security:spring-security-web:

> Task :dependencyInsight
org.springframework.security:spring-security-web:5.1.6.RELEASE (selected by rule)
   variant "compile" [
      org.gradle.status             = release (not requested)
      org.gradle.usage              = java-api
      org.gradle.component.category = library (not requested)
   ]

org.springframework.security:spring-security-web:4.2.13.RELEASE -> 5.1.6.RELEASE
\--- com.mycompany:my-security-plugin:0.3.0-SNAPSHOT:20200122.162056-4
     \--- compileClasspath

Обновление 3

buildEnvironment включает в себя следующее через grails:

 +--- org.springframework.boot:spring-boot-gradle-plugin:2.1.9.RELEASE
|    |    +--- org.springframework.boot:spring-boot-loader-tools:2.1.9.RELEASE (*)
|    |    +--- io.spring.gradle:dependency-management-plugin:1.0.8.RELEASE

1 Ответ

1 голос
/ 08 февраля 2020

Правильно ли я предполагаю, что вы используете плагин управления зависимостями Spring (io.spring.dependency-management) и, возможно, также плагин Spring Boot Gradle (org.springframework.boot)? Тогда весьма вероятно, что эта комбинация также будет управлять возможной версией spring-security-core для вас, независимо от того, какие другие части вашего запроса на установку сборки.

Минимальная настройка, демонстрирующая проблему

У меня есть следующие две сборки Gradle, сидящие рядом друг с другом (для краткости опущены файлы оболочки Gradle 5.1.1):

my-security-plugin
└── build.gradle
my-client
├── build.gradle
└── settings.gradle

Выполнение следующей команды Gradle из my-client дает мне (примерно) тот же вывод как в вопросе ОП:

./gradlew dependencyInsight --configuration compile --dependency org.springframework.security:spring-security-core

my-security-plugin/build.gradle

plugins {
    id 'java'
}

group = 'com.mycompany'
version = '0.3.0-SNAPSHOT'

repositories {
    jcenter()
}

dependencies {
    compile ('org.springframework.security:spring-security-core:4.2.13.RELEASE') {
        force = true
    }
    compile 'org.springframework.security:spring-security-config:4.2.13.RELEASE'
    compile 'org.springframework.security:spring-security-web:4.2.13.RELEASE'
}

my-client/build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.1.7.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
}

group = 'com.mycompany'
version = '1.0.0'

repositories {
    jcenter()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-security'
    compile 'com.mycompany:my-security-plugin:0.3.0-SNAPSHOT'
}

my-client/settings.gradle

includeBuild '../my-security-plugin'

Этот файл предназначен только для определения составной сборки Gradle; includeBuild не будет в рабочей сборке, вы скорее всего опубликуете sh my-security-plugin в каком-либо хранилище, откуда my-client загружает его.

Возможные решения проблемы

Как уже упоминалось во введении, сочетание плагина Spring Dependency Management и Spring Boot Gradle Plugin определяет версию spring-security-core для вашей сборки. Помимо вашего собственного обходного пути, есть три возможности получить нужную версию:

  1. Используйте версию Spring Boot, которая выбирает ту же версию spring-security-core, которая вам нужна: id 'org.springframework.boot' version '1.5.22.RELEASE'
  2. Настройте управляемые версии , установив дополнительное свойство в вашей сборке: ext['spring-security.version'] = '4.2.13.RELEASE'
  3. Не позволяйте Spring управлять вашими зависимостями вообще ...

Очевидно, что все эти решения имеют недостатки:

  • решение 1 вынуждает вас использовать старую версию Spring Boot
  • решение 2 вынуждает вас запрашивать требуемую версию переходной зависимости в вашем клиентское приложение (которое похоже на ваш собственный обходной путь, которого вы хотели избежать)
  • решение 3 может не стоить дополнительной работы, которая потребовала бы ручного управления всеми зависимостями Spring

Теперь вы нужно только выбрать меньшее зло; -)

...