Gradle - копировать файл после его генерации


Я пытаюсь создать банку и после этого скопировать ее в другую папку.

task createJar(type: Jar) {
    archiveName = "GradleJarProject.jar"
    manifest {
        attributes 'Implementation-Title': 'Gradle Jar File Example',  
            'Implementation-Version': version,
            'Main-Class': 'me.test.Test'
    }
    baseName = project.name
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar

}

task copyJarToBin {
    copy {
        from 'build/libs/GradleJarProject.jar'
        into "d:/tmp"
    }
}

task buildApp (dependsOn: [clean, createJar, copyJarToBin])

Но я не могу понять одну проблему. copyJarToBin задача попытаться скопировать старую банку. Если я удаляю/создаю папку в проекте и запускаю задачу buildApp(), задача createJar() будет генерировать файл .jar, но copyJarToBin() не найдет этот .jar файл.

Не могли бы вы мне помочь?
Спасибо.

Ответ 1

Виновником является ваша задача copyJarToBin. при выполнении

task copyJarToBin {
    copy {
        from 'build/libs/GradleJarProject.jar'
        into "d:/tmp"
    }
}

Вы копируете банку во время конфигурации, используя метод copy. (см. руководство пользователя gradle по адресу https://docs.gradle.org/current/userguide/userguide_single.html#sec:build_phases для понимания жизненного цикла сборки). Вы хотите запустить фактическую операцию копирования во время фазы выполнения (выполнения задание).

Один из способов решить эту проблему - переместить вызов метода copy в блок doLast:

task copyJarToBin {
    doLast {
        copy {
            from 'build/libs/GradleJarProject.jar'
            into "d:/tmp"
        }

    }
}

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

Лучший и более идиоматический способ написания задачи copyJarToBin - изменить реализацию задачи на использование типа задачи Copy:

task copyJarToBin(type: Copy) {
    from 'build/libs/GradleJarProject.jar'
    into "d:/tmp"
}   

Мы даже можем улучшить этот фрагмент, воспользовавшись функцией автоматического подключения Gradle. Вы можете объявить вывод одной задачи как ввод для другой. Поэтому вместо написания 'build/libs/GradleJarProject.jar' вы можете просто сделать:

task copyJarToBin(type: Copy) {
    from createJar // shortcut for createJar.outputs.files
    into "d:/tmp"
}   

Теперь вам не нужно беспокоиться об упорядочении задач, так как Gradle знает, что задача createJar должна быть выполнена до того, copyJarToBin задача copyJarToBin может быть выполнена.

Ответ 2

Я думаю, что вышеупомянутый ответ как-то старый. Вот ответ, используя gradle 3.3

jar {
    baseName = 'my-app-name'
    version =  '0.0.1'
}

task copyJar(type: Copy) {
    from jar // here it automatically reads jar file produced from jar task
    into 'destination-folder'
}

build.dependsOn copyJar

Ответ 3

Вероятно, вам нужно убедиться, что они запущены в правильном порядке,

task copyJarToBin(type:Copy,dependsOn:[createJar]) {
   copy {
     from "${buildDir}/GradleJarProject.jar"  // needs to be gstring       
     into "d:/tmp"
    }
}