Преобразование транзитивной зависимости в зависимость compileOnly

Я пытаюсь использовать OSGI, чтобы позволить мне использовать две разные версии транзитивной зависимости. План состоит в том, что одна версия (более новая) будет скрыта внутри пакета OSGI, а другая будет находиться в пути к классам среды выполнения, как обычно.

Я создал банку пакета с помощью Gradle (с Groovy DSL), но проблема в том, что связанные с ним зависимости времени выполнения неверны - он содержит более новую версию, которая должна быть скрыта внутри пакета. Это все еще верно, когда я делаю это в файле build.gradle:

compileOnly deps.diffx
runtimeOnly(deps.diffx) {
    exclude group: 'com.propensive', module: 'magnolia_' + versions.scala_v
}

Если я проверю зависимости с помощью задачи Gradle dependencies, то увидим, что магнолия исключена из конфигурации runtimeOnly, как и ожидалось, но не исключена из конфигурации runtimeClasspath.

Если я затем использую ./gradlew dependencyInsight --dependency magnolia_2.12 --configuration runtime, чтобы попытаться выяснить, откуда берется эта зависимость, он говорит мне, что более новая версия происходит от runtimeClasspath в зависимости от diffx, и это выбирается через разрешение конфликтов. Ну спасибо - это я уже знал. Вопрос в том, почему мое исключение не применяется к производной конфигурации?

В основном я хочу сделать противоположное этот вопрос.

Я также пробовал версии с ограничениями, но они показали ту же проблему:

compileOnly deps.diffx
runtimeOnly(deps.diffx) {
    constraints {
        implementation('com.propensive:magnolia_' + versions.scala_v + ':0.10.0') {
            because 'this version is required by our other dependencies'
        }
    }
}

person Robin Green    schedule 05.05.2021    source источник


Ответы (1)


Из документации Gradle:

С другой стороны, обработка исключения Gradle, в отличие от Maven, учитывает весь граф зависимостей. Таким образом, если есть несколько зависимостей от библиотеки, исключения выполняются только в том случае, если все зависимости согласуются с ними. Например, если мы добавим opencsv в качестве еще одной зависимости к нашему вышеприведенному проекту, который также зависит от commons-beanutils, коллекция commons больше не будет исключена, так как сам opencsv не исключает ее.

Вместо этого мы можем использовать правило разрешения зависимостей:

def magnoliaVersion = '0.10.0'

configurations.runtimeClasspath {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        if (details.requested.group == 'com.propensive' && details.requested.name.startsWith("magnolia_") && details.requested.version != magnoliaVersion) {
            details.useVersion magnoliaVersion
            details.because 'this version is required by our other dependencies'
        }
    }
}

а затем снова измените зависимость на простую одиночную implementation:

implementation deps.diffx

К сожалению, как отмечается в документации, это правило разрешения не опубликовано, поэтому его необходимо снова применить во всех зависимых модулях Gradle.

person Robin Green    schedule 05.05.2021