Рубрики
Без рубрики

исправление (транзитивной) проблемы с зависимостями с помощью gradle

путаница с транзитивной зависимостью При извлечении ядра openapi-процессора из openapi-процесса… С тегом gradle, java.

При извлечении ядра openapi-процессора из откройте acpi-процессор-пружину Я заметил повторяющиеся зависимости с разными, а иногда и неожиданными версиями в разделе внешние библиотеки представления проекта (в IDEA).

В данном случае Джексон упаковывает.

Запуск зависимостей gradle , чтобы увидеть, откуда они берутся, выводит следующий вывод (найдите jackson ):

зависимости градации (упрощенные)

+--- com.fasterxml.jackson.module:jackson-module-kotlin:2.11.0
|    +--- com.fasterxml.jackson.core:jackson-databind:2.11.0 <1>
|    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.11.0
|    |    \--- com.fasterxml.jackson.core:jackson-core:2.11.0
|    \--- com.fasterxml.jackson.core:jackson-annotations:2.11.0
+--- org.openapi4j:openapi-parser:1.0
|    \--- org.openapi4j:openapi-core:1.0
|         +--- com.fasterxml.jackson.core:jackson-databind:2.9.10 -> 2.11.0 (*) <2>
|         \--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.9.10 -> 2.10.2 <3>
|              \--- com.fasterxml.jackson.core:jackson-core:2.10.2 -> 2.11.0 <4>
+--- io.swagger.parser.v3:swagger-parser:2.0.20
     +--- io.swagger.parser.v3:swagger-parser-v3:2.0.20
          +--- io.swagger.core.v3:swagger-models:2.1.2
          |    \--- com.fasterxml.jackson.core:jackson-annotations:2.10.1 -> 2.11.0 <5>
          +--- io.swagger.core.v3:swagger-core:2.1.2
          |    +--- com.fasterxml.jackson.core:jackson-annotations:2.10.1 -> 2.11.0
          |    +--- com.fasterxml.jackson.core:jackson-databind:2.10.1 -> 2.11.0 (*)
          |    +--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.1 -> 2.10.2 (*) <6>
          |    +--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.1 <7>
          |         +--- com.fasterxml.jackson.core:jackson-annotations:2.10.1 -> 2.11.0
          |         +--- com.fasterxml.jackson.core:jackson-core:2.10.1 -> 2.11.0
          |         \--- com.fasterxml.jackson.core:jackson-databind:2.10.1 -> 2.11.0 (*)
          +--- com.fasterxml.jackson.core:jackson-annotations:2.10.2 -> 2.11.0
          +--- com.fasterxml.jackson.core:jackson-databind:2.10.2 -> 2.11.0 (*)
          \--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2 (*) <8>

Существует небольшая путаница в отношении пакетов Джексона и их версий. Вот несколько записей:

<1> некоторые с версией 2.11.0 <2> обновление с 2.9.10 до 2.11.0 <3> обновление с 2.9.10 до 2.10.2 <4> обновление с 2.10.2 до 2.11.0 <5> обновление с 2.10.1 до 2.11.0 <6> обновление с 2.10.1 до 2.10.2 <7> версия 2.10.1 <8> версия 2.10.2

3 зависимости верхнего уровня являются прямыми зависимостями (как их называет gradle) моего проекта, и все они используют разные версии Джексона:

. com.fasterxml.jackson.модуль: джексон-модуль-котлин:2.11.0 . org.openapi: openapi-анализатор:1.0 . io.swagger.parser.v3: swagger-парсер:2.0.20

Первый из них прост. Потому что com.fasterxml.jackson.module: джексон-модуль-котлин является ли сам пакет Джексона, gradle выбирает 2.11.0 для других переходных зависимостей Джексона.

джексон-модуль-котлин (упрощенный)

    +--- com.fasterxml.jackson.module:jackson-module-kotlin:2.11.0
         +--- com.fasterxml.jackson.core:jackson-annotations:2.11.0
         +--- com.fasterxml.jackson.core:jackson-core:2.11.0
         \--- com.fasterxml.jackson.core:jackson-databind:2.11.0

Следующий – это org.openapi: openapi-анализатор:1.0 . Это зависит от Джексона 2.9.10 и gradle обновляет все до 2.11.0 потому что это самая новая версия, которую он нашел.

открытый api-анализатор (упрощенный)

+--- org.openapi4j:openapi-parser:1.0
     +--- com.fasterxml.jackson.core:jackson-core:2.10.2 -> 2.11.0
     +--- com.fasterxml.jackson.core:jackson-databind:2.9.10 -> 2.11.0 (*)
     \--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.9.10 -> 2.10.2

Хорошо, не для всех посылок Джексона. Он не использует 2.11.0 для джексон-формат данных-yaml .

Он не использует 2.11.0 потому что gradle не видел более новой версии jackson-dataformat-yaml чем 2.9.10 . Так почему же это не так 2.9.10 ? Это не потому, что третья прямая зависимость io.swagger.parser.v3:swagger-parser:2.0.20 использует 2.10.1 и 2.10.2 .

swagger-анализатор (упрощенный)

+--- io.swagger.parser.v3:swagger-parser:2.0.20
     +--- com.fasterxml.jackson.core:jackson-annotations:2.10.1 -> 2.11.0
     +--- com.fasterxml.jackson.core:jackson-core:2.10.1 -> 2.11.0
     +--- com.fasterxml.jackson.core:jackson-databind:2.10.1 -> 2.11.0
     +--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.1 -> 2.10.2
     \--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.1

2.10.2 для Джексона-формат данных-yaml . Это самая высокая версия для этого пакета, поэтому gradle выбирает ее.

Gradle окончательно выбирает следующие версии:

2.11.0 ядро: джексон-аннотации
2.11.0 ядро: джексон-ядро
2.11.0 ядро: джексон-привязка данных
2.10.2 => хочу 2.11.0 формат данных: джексон-формат данных-yaml
2.10.1 => хочу 2.11.0 тип данных: джексон-тип данных-jsr310

Gradle использует самую высокую версию, которую он находит для каждого пакета. Он не знает, что пакеты Джексона принадлежат друг другу и что все они должны использовать одну и ту же версию.

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

решение

В соответствии с документацией gradle предпочтительным решением является добавление блока ограничений в зависимости . Добавление прямой зависимости не является правильным решением:

градуированные ограничения

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

Изменение правил разрешения зависимостей также не является вариантом:

правила разрешения зависимостей gradle

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

ограничения

Проект представляет собой библиотеку, и решение ограничений выглядит следующим образом в build.gradle :

ext {
    jacksonVersion = '2.11.0'
}

dependencies {
    // .. dependencies ..

    constraints {
        implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jacksonVersion") {
            because 'use the same version for all jackson packages'
        }
        implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jacksonVersion") {
            because 'use the same version for all jackson packages'
        }
    }

}

Хорошо, это устраняет проблему.:-)

Жаль, что каждый отдельный пакет требует своего собственного ограничения (закрытие с потому что не требуется). Было бы неплохо использовать подстановочные знаки, чтобы сопоставить все пакеты Джексона с одним ограничением:

ext {
    jacksonVersion = '2.11.0'
}

dependencies {
    // .. dependencies ..

    constraints {
        // does NOT work
        implementation("com.fasterxml.jackson.*:*:$jacksonVersion") {
            because 'use the same version for all jackson packages'
        }
    }

}

Это было бы немного проще но, к сожалению, это не работает.

платформа

Я нашел другое решение в документации gradle, которое даже использует Джексона в качестве примера:

выравнивание версий зависимостей gradle .

Первым шагом является создание правила метаданных, которое объединяет все пакеты Джексона в платформу . У Джексона есть спецификация платформы, в которой перечислены все пакеты, принадлежащие версии платформы, и она используется для создания правила платформы:

class JacksonPlatformRule implements ComponentMetadataRule {
    void execute (ComponentMetadataContext ctx) {
        ctx.details.with {
            if (id.group.startsWith ("com.fasterxml.jackson")) {
                belongsTo ("com.fasterxml.jackson:jackson-bom:${id.version}", false)
            }
        }
    }
}

Я просто добавил класс в конце build.gradle для тестирования, но он, вероятно, переместится в колыбели создайте Src

Второй шаг – активировать правило в блоке зависимости :

dependencies {
    components.all(JacksonPlatformRule)

    // .. dependencies ..
}

Группируя пакеты, gradle теперь выбирает платформу джексона | с самой высокой версией и использует версии, перечисленные в спецификации для любого пакета Джексона.

Это также видно в выводе зависимостей gradle (начиная со строки 4). Сортировка выбирает 2.11.0 модуль платформы и обновляет все пакеты Джексона до версии платформы:

зависимости градации (упрощенные)

+--- com.fasterxml.jackson.module:jackson-module-kotlin:2.11.0
|    +--- com.fasterxml.jackson.core:jackson-databind:2.11.0
|    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.11.0
|    |    |    \--- com.fasterxml.jackson:jackson-bom:2.11.0
|    |    |         +--- com.fasterxml.jackson:jackson-bom:2.11.0 (*)
|    |    |         +--- com.fasterxml.jackson.core:jackson-annotations:2.11.0 (c)
|    |    |         +--- com.fasterxml.jackson.core:jackson-core:2.11.0 (c)
|    |    |         +--- com.fasterxml.jackson.core:jackson-databind:2.11.0 (c)
|    |    |         +--- com.fasterxml.jackson.module:jackson-module-kotlin:2.11.0 (c)
|    |    |         +--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.11.0 (c)
|    |    |         \--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.11.0 (c)
|    |    +--- com.fasterxml.jackson.core:jackson-core:2.11.0
|    |    |    \--- com.fasterxml.jackson:jackson-bom:2.11.0 (*)
|    |    \--- com.fasterxml.jackson:jackson-bom:2.11.0 (*)
|    +--- com.fasterxml.jackson.core:jackson-annotations:2.11.0 (*)
|    \--- com.fasterxml.jackson:jackson-bom:2.11.0 (*)
+--- org.openapi4j:openapi-parser:1.0
|    \--- org.openapi4j:openapi-core:1.0
|         +--- com.fasterxml.jackson.core:jackson-databind:2.9.10 -> 2.11.0 (*)
|         \--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.9.10 -> 2.11.0
|              +--- com.fasterxml.jackson.core:jackson-databind:2.11.0 (*)
|              +--- org.yaml:snakeyaml:1.26
|              +--- com.fasterxml.jackson.core:jackson-core:2.11.0 (*)
|              \--- com.fasterxml.jackson:jackson-bom:2.11.0 (*)
+--- io.swagger.parser.v3:swagger-parser:2.0.20
     +--- io.swagger.parser.v3:swagger-parser-v3:2.0.20
          +--- io.swagger.core.v3:swagger-models:2.1.2
          |    \--- com.fasterxml.jackson.core:jackson-annotations:2.10.1 -> 2.11.0 (*)
          +--- io.swagger.core.v3:swagger-core:2.1.2
          |    +--- com.fasterxml.jackson.core:jackson-annotations:2.10.1 -> 2.11.0 (*)
          |    +--- com.fasterxml.jackson.core:jackson-databind:2.10.1 -> 2.11.0 (*)
          |    +--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.1 -> 2.11.0 (*)
          |    \--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.1 -> 2.11.0
          |         +--- com.fasterxml.jackson.core:jackson-annotations:2.11.0 (*)
          |         +--- com.fasterxml.jackson.core:jackson-core:2.11.0 (*)
          |         +--- com.fasterxml.jackson.core:jackson-databind:2.11.0 (*)
          |         \--- com.fasterxml.jackson:jackson-bom:2.11.0 (*)
          +--- com.fasterxml.jackson.core:jackson-annotations:2.10.2 -> 2.11.0 (*)
          +--- com.fasterxml.jackson.core:jackson-databind:2.10.2 -> 2.11.0 (*)
          \--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2 -> 2.11.0 (*)

заключение

Решение ограничения легко использовать для отдельных зависимостей. Правило платформы – это путь для групп пакетов, таких как jackson.

Это оно.

Оригинал: “https://dev.to/hauner/fixing-a-transitive-dependency-mess-with-gradle-1g5”