Подтвердить что ты не робот

Gradle - исключить зависимость для конфигурации, но не для наследующей конфигурации

Использование Gradle 1.0 веха 8.

В моем проекте используется slf4j + Logback для ведения журнала, поэтому я хочу, чтобы любые транзитивные отпечатки на log4j не загрязняли мой путь к классам. Таким образом, я добавил глобальное исключение, например:

configurations {
    all*.exclude group: "log4j", module: "log4j"
}

Тем не менее, я использую тестовую библиотеку (hadoop-minicluster), которая имеет зависимость от времени выполнения от log4j, поэтому теперь мне нужно разрешить зависимость log4j для моей тестовой версии. Я попытался добавить прямую зависимость от log4j:

testRuntime group: "log4j", name: "log4j", version: "1.2.15"

и редактирование моего кода исключения (немного взлома):

configurations.findAll {!it.name.endsWith('testRuntime')}.each { conf ->
    conf.exclude group: "log4j", module: "log4j"
}

Но это не работает. Добавление исключения в testCompile conf автоматически добавляет его ко всем наследующим конфигурациям, включая testRuntime. И похоже, что это исключение переопределяет даже явную зависимость, которую я добавил.

Похоже, что это ожидаемое поведение для Gradle. Из документы:

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

Так есть ли другой способ сделать то, что я хочу достичь?

Идеи:

  • Создайте новый conf myTestRuntime, который не распространяется на testCompile, и используйте его для моего тестового пути.
    • Но тогда я должен дублировать все зависимости как для testCompile, так и для myTestRuntime.
  • Удалить исключения на уровне конфигурации. Для всех confs помимо testRuntime, зацикливайте зависимости и вручную удалите log4j (или добавьте исключение уровня dep на log4j).
    • Возможно ли это? Configuration.allDependencies доступен только для чтения.
4b9b3361

Ответ 1

На данный момент мне удалось решить проблему, но я по-прежнему приветствую любые лучшие решения.

Вот что я сделал:

  • Добавьте новую конфигурацию только для log4j:

    log4j(group: 'log4j', name: 'log4j', version: '1.2.15') {
        transitive = false
    }
    
  • Оставьте исключение на уровне конфигурации для всех конфигураций, кроме этого:

    configurations.findAll {!it.name.endsWith('log4j')}.each { conf ->
        conf.exclude group: "log4j", module: "log4j"
    }
    
  • Добавьте конфигурацию log4j в путь к классам моих тестов:

    test {
        classpath += configurations.log4j
    }
    

Таким образом, мы можем получить log4j.jar в пути к классам, даже если он исключен из конфигурации testRuntime.

Ответ 2

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

configurations{
    runtime.exclude group: 'log4j'
}

test {
        classpath += configurations.compile
}

Ответ 3

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