Мультипроект Gradle дает Не удалось найти свойство 'sourceSets' при ошибке проекта

У меня была неплохая конфигурация Gradle, в которой все было просто отлично. Но один из проектов моей многопроектной сборки настолько унаследован от остальных, что я с удовольствием переместил бы его в другое репозиторий git и настроил подмодули для его обработки.

Сначала я переместил проект и его ресурсы в подпапку Libraries/MovedProject. После изменения некоторых строк в конфигурациях gradle все заработало нормально. Но потом я решил написать новый build.gradle именно под этот проект, и перенести туда все конфигурации из основного.

И тут все перестало работать. Когда я пытаюсь вызвать любую задачу, она всегда заканчивается на Could not find property 'sourceSets' on project ':Libraries/MovedProject'. Строка, которая за это отвечает:

dependencies {
    ...
    if (noEclipseTask) {
        testCompile project(':Libraries/MovedLibrary').sourceSets.test.output
    }
}

который я использую для запуска тестов, в которых я использую классы из других проектов. Если я удалю эту строку, сборка завершится ошибкой только тогда, когда она достигнет задачи compileTestJava проектов, использующих MovedProject. Если я удалю эту строку и вызову gradle :Libraries/MovedLibrary:properties, я увижу:

...
sourceCompatibility: 1.7
sourceSets: [source set main, source set test]
standardOutputCapture: org.gradle.logging.internal.DefaultLoggingManager@1e263938
...  

в то время как gradle :Libraries/MovedLibrary:build строится правильно.

В настоящее время у меня все настроено следующим образом:

  1. каталоги:

    • /SomeMainProject1
    • /SomeMainProject2
    • /SomeMainProject3
    • /Libraries
      • /MovedProject
        • build.gradle
        • зависимости.gradle
        • проект.градле
        • задачи.градле
    • /Builder
      • dependencies.gradle
      • проект.градле
      • задачи.градле
    • build.gradle
    • настройки .градле
  2. настройки .градле

    include Libraries/MovedProject,
            SomeMainProject1,
            SomeMainProject2,
            SomeMainProject3
    
  3. Исходные наборы для MovedProject определены в Libraries/MovedProject/project.gradle:

    sourceSets {
        main {
            java {
                srcDir 'src'
                srcDir 'resources'
            }
            resources { srcDir 'resources' }
        }
        test { java {
            srcDir 'test/unit'
        } }
    }
    
  4. зависимости, которые используют sourceSets.test.output, хранятся в Builder/dependancies.gradle и устанавливаются для каждого проекта, которому требуется MovedProject для запуска тестов:

    project(':SomeMainProject1') {
        dependencies {
            ...
    
            if (noEclipseTask) {
                testCompile project(':Libraries/net.jsdpu').sourceSets.test.output
            }
        }
    }
    

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


person Mateusz Kubuszok    schedule 11.03.2013    source источник


Ответы (1)


Рассматриваемая строка проблематична, поскольку предполагает, что проект :Libraries/MovedLibrary оценивается (не выполняется) до текущего проекта, что может быть не так. А если нет, то наборы исходников другого проекта еще не настроены. (Не будет даже свойства sourceSets, потому что плагин java-base еще не применен.)

Как правило, лучше не обращаться к моделям проектов других проектов, особенно если они не являются дочерними элементами текущего проекта. В случае проекта A, использующего тестовый код проекта B, рекомендуемое решение состоит в том, чтобы проект B предоставил тестовый Jar (через блок artifacts {}), который затем используется проектом A.

Если вы хотите оставить все как есть, вы можете обойти проблему, используя gradle.projectsEvaluated {} или project.evaluationDependsOn(). Дополнительные сведения см. в Справочнике по языку сборки Gradle.

person Peter Niederwieser    schedule 12.03.2013
comment
Большое спасибо! Теперь все строится. Используется свойство project.evaluationDependsOn(). Я предполагаю, что это решение грязное, но я должен придерживаться его некоторое время. - person Mateusz Kubuszok; 12.03.2013