Как установить свойство задачи лениво?

task task1(type: ProduceFilesTaskType) {
   outDir = file("$projectDir/some/files")
}

task task2(type: ConsumeFilesTaskType) {
   fileList = file("$doSomething.outDir/somefolders/").listFiles().toList() // null pointer exception
}

У меня нет источника ConsumeFilesTaskType, и для этого требуется List<File> fileList, созданный task1.

Теперь, поскольку эти файлы не существуют на этапе настройки, gradle завершается сбоем на этапе настройки с ошибкой Cannot invoke method toList() on null object из-за отсутствия файлов.

Я, наверное, могу это сделать

task task2(type: ConsumeFilesTaskType) {
   fileList = new ArrayList<File>() // don't fail
   doFirst {
      fileList = file("$doSomething.outDir/somefolders/").listFiles().toList() // actual list of files
   }
}

Это стандартный способ или есть лучший способ лениво установить/оценить свойство?

doFirst, doLast — стандартный способ

daggett 10.12.2020 18:05

@daggett вместе с инициализацией свойства с пустым экземпляром?

SMUsamaShah 10.12.2020 18:08

Исключение нулевого указателя возникает не потому, что fileList имеет значение null, а file("$doSomething.outDir/somefolders/") возвращает значение null. Я не думаю, что вам нужен fileList = new ArrayList<File>(), если не происходит что-то еще

Xinchao 10.12.2020 18:43
Gradle за прокси-сервером
Gradle за прокси-сервером
Создайте проект Gradle под сетевым прокси.
"DevOps: Jenkins & AWS Series, часть 5: Установка Gradle на Ubuntu 22.04
"DevOps: Jenkins & AWS Series, часть 5: Установка Gradle на Ubuntu 22.04
В этой статье блога мы проведем вас через процесс установки Gradle на Ubuntu 22.04, интеграции его с Jenkins и создания задания Gradle. Мы...
0
3
91
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В Gradle есть множество конструкций, которые оцениваются лениво. В некотором смысле Gradle построен на основе идеи ленивых вычислений. При этом это также зависит от того, как реализован ваш ConsumeFilesTaskType. Ничего не поможет, если сама задача не лениво использует параметр fileList.

Если fileList имеет тип Iterable<File> или предоставленный Gradle тип FileCollection, вы можете назначить его для project.fileTree() на этапе настройки:

Iterable<File> fileList;

task myTask {
    fileList = project.fileTree("build") // build might not exist at this moment
    
    doLast {
        fileList.forEach { println it.name }
    }
}

Существует аналогичный метод project.files(), который создает объект ConfigurableFileCollection. Документация project.files() лучше объясняет, что значит «ленивый» и «живой». project.fileTree() возвращает ConfigurableFileTree, который также является ленивым и живым. Разница в том, что ConfigurableFileTree интерпретирует добавленные файлы как корневые. При повторении ConfigurableFileTree рекурсивно обходит эти корневые каталоги, чтобы собрать фактические файлы для вызывающего объекта.

Другие вопросы по теме