Q: Sequencing dependencies of multiple Gradle plugin tasks Please note: Although I specifically mention two Gradle plugins here, this is 100% a question about understanding task dependencies in Gradle, and does not require any knowledge of the individual plugins (I think)!

I have a project that will use two Gradle plugins:


*

*The Gradle Shadow plugin, which will produce a self-contained "fat jar" (basically a large jar with all my classes plus the classes of all my transitive dependencies, which then allows me to just run java -jar myapp.jar without having to manage the jar's external classpath, etc.). This will produce a fat jar at build/libs/myapp.jar; and

*The Gradle Launch4J plugin, which uses Launch4J under the hood to convert a jar into a native executable (EXE, etc.). Obviously the fat jar has to be created prior to the Launch4J tasks run, otherwise they'll have nothing to wrap inside of an EXE!
Here's my build.gradle:
import com.github.jengelman.gradle.plugins.shadow.transformers.ServiceFileTransformer

plugins {
    id 'groovy'
    id 'application'
    id 'maven-publish'
    id 'com.github.johnrengelman.shadow' version '1.2.3'
    id 'edu.sc.seis.launch4j' version '2.3.0'
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

group = 'hotmeatballsoup'
mainClassName = 'com.me.myapp.Driver'

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    compile(
        'org.codehaus.groovy:groovy-all:2.4.7'
        ,'org.slf4j:slf4j-api:1.7.24'
        ,'org.slf4j:slf4j-simple:1.7.24'
    )
}

manifest {
    attributes 'Main-Class': mainClassName
}
jar {
    manifest {
        attributes 'Main-Class': mainClassName
    }
    baseName = 'zimbus'
}

shadowJar {
    transform(ServiceFileTransformer) {
        exclude 'META-INF/*.DSA'
        exclude 'META-INF/*.RSA'
        exclude 'LICENSE*'
    }
    transform(com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer) {
        resource = 'reference.conf'
    }
    classifier = ''
}

publishing {
    publications {
        shadow(MavenPublication) {
            from components.shadow
            artifactId = 'zimbus'
        }
    }
}

launch4j {
    outfile = 'zimbus.exe'
    mainClassName = 'com.me.myapp.Driver'
    icon = 'zimbus.ico'
    jar = 'build/libs/gradle-launch4j-example.jar'
}

At the command-line I run:
./gradlew clean build shadowJar createAllExecutables

The intention here is that I want the fat jar created first (invoked when shadowJar runs) and then for Launch4J to kick in (which is invoked when createAllExecutables runs). But when I run this I get the following exception:
:createExe FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':createExe'.
> Launch4J finished with non-zero exit value 1
  launch4j: Application jar doesn't exist.

I'm pretty sure the createAllExecutables task is firing before the shadowJar task, and thus having nothing (no fat jar) to bundle up inside an EXE.
Can someone confirm my suspicion and help me define the dependsOn declaration that will order my tasks correctly? Or if the tasks are executing in the correct order, maybe offer any ideas as to what is causing the error?

A: Once you write 

createAllExecutables.dependsOn shadowJar

you'll define the dependency between createAllExecutables task and shadowJar, which means every time Gradle decide to invoke createAllExecutables (e.g. because you pass that to the command line, or other task will depend on it) shadowJar will also be added to the task graph. So in that case when you invoke gradle createAllExecutables the shadowJar will be also executed.
But you can also write

createAllExecutables.mustRunAfter shadowJar

In that case, you won't introduce any dependency relation between tasks, but you will instrument Gradle about anticipated order for those two tasks. In that case, once you invoke gradle createAllExecutables the shadowJar won't be executed.
I think the dependsOn relation is more applicable in your case, since in order to create executables you need to have fat jar already, so it's a depend on relation, not must run after.
