smeeb
smeeb

Reputation: 29507

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:

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?

Upvotes: 0

Views: 384

Answers (1)

grzlew
grzlew

Reputation: 590

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.

Upvotes: 1

Related Questions