I've got a gradle build with source and javadoc jars and I'd like these tasks to be executed before distZip and distTar, is there a dependency that captures both of those for use with shouldRunAfter.
Right now I've got:
task javadocJar(type: Jar) {
classifier 'javadoc'
from javadoc
}
task sourcesJar(type: Jar) {
classifier 'sources'
from sourceSets.main.allSource
}
tasks.distZip.shouldRunAfter tasks.javadocJar
tasks.distTar.shouldRunAfter tasks.javadocJar
tasks.distZip.shouldRunAfter tasks.sourcesJar
tasks.distTar.shouldRunAfter tasks.sourcesJar
I'd like to condense down those four shouldRunAfter to two which captures both distZip and distTar.
You can use groovy syntax to make this shorter
[distZip, distTar]*.shouldRunAfter javadocJar, sourcesJar
Probably you also want dependsOn instead of shouldRunAfter so that the jars are built whenever one of the dist tasks is enabled.
Related
In my Gradle project, I define an additional sourceSet.
sourceSets {
sample {
java {
srcDir 'sample/java'
}
compileClasspath += sourceSets.main.output + sourceSets.main.compileClasspath
}
}
I then add a task:
task sampleJar(type: Jar) {
classifier 'sample'
from sourceSets.sample.output
}
artifacts {
archives sampleJar
}
If I do > gradle build the additional jar file builds from the additional source set. However, if I do > gradle jar, it doesn't. any reason why?
When I go through the output messages, I see:
gradle build has sampleJar in the Tasks to be executed:
but
gradle jar doesn't.
But unsure as to why?
Because jar is just the task that assembles the main jar file.
build, on the other hand, is the top-level life-cycle task, which depends on assemble. And assemble is documented as
Depends on: jar, and all other tasks that create artifacts attached to the archives configuration.
Since your sampleJar pecisely creates an artifact attached to the archives configuration, assemble, and thus build depends on it.
I have the following task:
task myJar(type: Jar) {
archiveName = 'myJar.jar'
includeEmptyDirs = false
destinationDir = rootProject.libsDir
dependsOn compileJava
manifest.attributes('Class-Path': '../lib/commons-lang-2.5.jar')
into '/', {
from compileJava.destinationDir
include 'com/myCompany/project/util/order/**',
'com/myCompany/project/event/**',
}
}
and I would like to relocate all classes from com/myCompany/project/event/** to com/myCompany/relocated/project/event/** (so that some apps using my jar and having com.myCompany.project.event package defined will avoid any possible conflicts)
I discovered that it can be done using shadow plugin and I tried to add
relocate 'com.myCompany.project.event.', 'com.myCompany.relocated.project.event.'
under this task but it doesn't seem to work.
Does anybody know where I should add this line?
You can achieve this by adding below plugin to your build.gradle
apply plugin: 'com.github.johnrengelman.shadow'
After adding this plugin add below code to your build.gradle file
shadowJar {
relocate 'com.myCompany.project.event', 'com.myCompany.relocated.project.event'
}
After adding this, to ensure your ShadowJar task runs before build, add this line at the end
assemble.dependsOn shadowJar
This will ensure that shadow jar task is triggered before assemble/build task during gradle build.
On doing the Gradle build, you should see all your packages and their corresponding dependencies relocated from 'com.myCompany.project.event' to 'com.myCompany.relocated.project.event'.
For more info you can refer to ShadowJarUserGuide
task myJar(type: Jar) {
doLast {
// process jar, e.g. proguard jar, override the same jar
tasks.proguardJar.execute()
}
}
Gradle creates hash for task inputs and outputs for UP_TO_DATE check. When will they be created? before doFirst and after doLast?
Before doFirst and after doLast sounds right.
Recent gradle versions are stricter when it comes to changes in the file containing doFirst and doLast blocks, though. Any textual change will now cause the task to be out-of-date.
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?
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.
I am new to Gradle and have gotten a fairly sophisticated build working with it so far (runs tests, uses CodeNarc, generates API docs, generates a sources JAR, etc.). The command line for a "full build" (that is, to execute all the major tasks that the CI server should be running), I need to enter the following Gradle command at the shell:
gradle clean build check groovydoc sourcesJar createPom dist -Pversion=<version>
Where <version> is the version I want to build.
I would like to condense this and add an alias so that all of the above can be accomplished with something simple, like:
gradle full-build
Is this possible? If so, how?
My build.gradle
apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'codenarc'
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.3'
testCompile 'junit:junit:4.11'
}
groovydoc
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
artifacts {
archives sourcesJar
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
task dist(type: Zip, dependsOn: build) {
classifier = 'buildreport'
from('build/test-results') {
include '*.xml'
into 'tests'
}
from('build/reports/codenarc') {
into 'reports'
}
from('build/docs') {
into 'api'
}
from(sourcesJar) {
into 'source'
}
from('build/libs') {
exclude '*-sources.jar'
into 'bin'
}
}
task createPom << {
pom {
project {
groupId "me"
artifactId "myapp"
version version
}
}.writeTo("build/libs/myapp-${version}.pom")
}
In the above build invocation, at least check and sourcesJar can be omitted already. (build depends on check, and from(sourcesJar) tells Gradle that dist depends on sourcesJar.) By adding further task dependencies (e.g. build.dependsOn dist), you can cut it down to gradle clean build -Pversion=.... dist should not depend on build but on the specific tasks that produce the artifacts that go into the zip (e.g. groovydoc and createPom).
Reducing gradle clean build to gradle fullBuild is more difficult, as Gradle doesn't currently have a first-class concept of "aliases", and adding build.dependsOn(clean) is usually not desirable. One way out is to implement your own aliasing mechanism by manipulating gradle.startParameter.taskNames.