Search code examples
javagradlebuild.gradlegradle-task

Gradle - export property after copy task finishes


I have a build pipeline where I want to run a particular jar (with some args) after copying it into a separate folder from the dependency list.

Currently I'm doing the following:

task copyToLib(type: Copy, dependsOn: classes) {
    into "$buildDir/server"
    from(configurations.compile) {
        include "webapp-runner*"
    }
    ext.serverPath =  fileTree("$buildDir/server/").include("webapp-runner-*.jar").getSingleFile()
}

task run(type: Exec, dependsOn: [copyToLib, war]) {
    mustRunAfter copyToLib
    executable 'java'
    args '-jar', copyToLib.serverPath, war.archivePath, '--port', "$port"
}

But it fails with Expected directory '...' to contain exactly one file, however, it contains no files. since I'm guessing serverPath is set during config phase when the file has not been copied. How do I get around this?


Solution

  • You are falling for the common mistake of executing logic in the configuration phase when you should be executing it in the execution phase.

    Try this

    task copyToLib(type: Copy, dependsOn: classes) {
        ...
        doLast {
            ext.serverPath = ...
        }
    }
    

    If it were me, I'd calculate serverPath inside run rather than in copyToLib. Perhaps you could use a closure to delay the calculation.

    Eg:

    task run(type: Exec, dependsOn: [copyToLib, war]) {
        def pathClosure = {
            fileTree("$buildDir/server/").include("webapp-runner-*.jar").singleFile
        }
        mustRunAfter copyToLib
        executable 'java'
        args '-jar', pathClosure, war.archivePath, '--port', "$port"
    }