SlideShare a Scribd company logo
1 of 41
Download to read offline
Improving your Gradle
builds
Peter Ledbrook
e: peter@cacoethes.co.uk
w: http://www.cacoethes.co.uk
t: @pledbrook
“Safety” in build tools
"Straight Razor" by Horst.Burkhardt - Own work.
Licensed under CC BY-SA 3.0 via Wikimedia Commons
Gradle is often treated like a cut-throat razor: unsafe
Code == spaghetti builds (allegedly)
Some people think it’s better to limit build authors to configuration only
Is this a good comparison though?
A better analogy
by Noel C. Hankamer - Creative Commons 2.0
Not all jobs are the same for a workman
Need the right tools for the job
Some tools are dangerous - so you learn to use them
Power drills, heavy duty knives, etc.
Gradle
Yes, you can create spaghetti builds, but…
“A bad workman blames
his tools”
So how do you create
maintainable builds?
First, understand the Gradle
model
Gradle is an API
Project
Task
Repository Dependency
Configuration Source set (Java)
This is just part of the Gradle model, which allows you to model your own build processes.
Show Gradle DSL and API references if possible: http://www.gradle.org/doc/latest/…
A basic Java build
apply	 plugin:	 "java"

version	 =	 "1.0"

repositories	 {	 jcenter()	 }

dependencies	 {

	 	 	 	 compile	 "asm:asm-all:3.3.1",

	 	 	 	 	 	 	 	 	 	 	 	 "commons-io:commons-io:1.4"

}

compileJava.options.incremental	 =	 true
An instance of Task
A Repository
Everything from Project
• project.tasks
• project.configurations
• project.repositories
• project.dependencies
• project.sourceSets (added by Java
plugin)
All the model elements are available from the project
The project itself can be accessed via the `project` property
The three phases
Initialisation
Configuration
Execution
Only relevant to multi-
project builds
Configures tasks and builds
the task graph
Executes the necessary tasks
based on the task graph
Beyond the model that defines the build, this is what happens when you actually run that build
At execution
Y
X
Z
=>
Z
X Y
W
V
Linear execution orderTask graph
W
V
During configuration Gradle builds a Directed Acyclic Graph (DAG) of tasks
Before execution, the graph is turned into an execution order
There is no distinction between targets and tasks like in Apache Ant
Applying that knowledge
Beware the config phase
Beware the config phase
• Configuration always happens
- even just running grade	 tasks!
- this will change soon(ish)
• Avoid expensive work
Profile your build!
gradle	 --profile	 <taskName>
This generates a report with timings for the different phases of each project in the build
Example
apply	 plugin:	 "java"

...

jar	 {

	 	 	 version	 =	 new	 URL("http://buildsvr/version").text

}
Evaluated every build!
(This will change soon in Gradle)
Potentially unreliable network call *every* time the build runs
No matter what tasks are executed
Gradle will perform configuration on-demand in the not too distant future, reducing the time cost of the configuration phase
Remember
task	 doSomething	 <<	 {

	 	 	 	 println	 "Doing	 it!"

}
task	 customJar(type:	 Jar)	 {

	 	 	 	 archivePath	 =	 customJarPath

	 	 	 	 doLast	 {

	 	 	 	 	 	 	 	 println	 "Created	 the	 JAR	 file"

	 	 	 	 }

} Execution
Execution
Configuration
Consider always using `doLast()` instead of `<<` to avoid confusion between configuration and implicit execution
Project properties
Project properties
• Useful for build parameterisation
• Equivalent to global variables
- Same problems!
• Provide sensible defaults
• Assume values are strings
Default values
ext	 {

	 	 	 	 jarFilename	 =	 project.hasProperty("jarFilename")

	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ?	 jarFilename	 :	 "myArchive"

}

task	 customJar(type:	 Jar)	 {

	 	 	 	 archivePath	 =	 file("$buildDir/$jarFilename")

	 	 	 	 doLast	 {

	 	 	 	 	 	 	 	 println	 "Created	 the	 JAR	 file:	 ${archivePath}"

	 	 	 	 }

}
Check property exists first
Default value
Values can be overridden via
-P cmd line option
gradle.properties
Both only support strings
Prefer task properties
task	 customClean(type:	 Delete)	 {

	 	 	 	 delete	 "$buildDir/$jarFilename"

}
task	 customClean(type:	 Delete)	 {

	 	 	 	 delete	 customJar.archivePath

}
Use the path defined
by the task
Don’t let project properties litter your build
If the JAR task stops using the project property, `customClean` will continue to work
Refactoring
Custom tasks
Prefer
task	 doIt(type:	 MyTask)

class	 MyTask	 extends	 DefaultTask	 {

	 	 	 	 @TaskAction

	 	 	 	 def	 action()	 {	 println	 "Hello	 world!"	 }

}
task	 doIt	 <<	 {

	 	 	 	 println	 "Hello	 world!"	 }

}
over
More verbose, but easier to maintain
Easier to incorporate properties in custom task classes
Easier to migrate the task implementation out of the build file
Custom tasks
Where the task class goes:
1. In build.gradle
2. In buildSrc/src/groovy/…
3. In a JAR file
IoC in tasks
class	 MyTask	 extends	 DefaultTask	 {

	 	 	 	 File	 filePath	 =	 project.myArchivePath

	 	 	 	 @TaskAction

	 	 	 	 def	 action()	 {

	 	 	 	 	 	 	 	 println	 filePath.text

	 	 	 	 }

}
Don’t pull values from
the environment
IoC in tasks
task	 doIt(type:	 MyTask)	 {

	 	 	 	 filePath	 =	 project.myArchivePath

}
Leave configuration in the build file
Effectively Inversion of Control - values should always be injected
Last one…
Consider breaking into multiple
smaller projects
Understand your build
Task order vs dependency
task	 functionalTest(type:	 Test,	 dependsOn:	 test)
task	 functionalTest(type:	 Test)	 {

	 	 	 	 mustRunAfter	 test

}
Do the functional tests require the unit tests to run?
Or is it just the order that counts?
Leverage source sets
Instead of
configurations	 {

	 	 	 	 clientCompile

}

task	 compileClient(type:	 JavaCompile)	 {

	 	 	 	 classpath	 ...

	 	 	 	 include	 "src/main/java/**/client/*"

}

//	 Don't	 forget	 the	 test	 tasks	 and	 dependencies!

...
Leverage source sets
Use source sets
sourceSets	 {

	 	 	 	 client	 {

	 	 	 	 	 	 	 	 java	 {

	 	 	 	 	 	 	 	 	 	 	 	 srcDirs	 file("src/main/java")

	 	 	 	 	 	 	 	 	 	 	 	 include	 "src/main/java/**/client/*"

	 	 	 	 	 	 	 	 }

	 	 	 	 }

}

Get:
• clientCompile, clientRuntime configurations
• compileClientJava task
Use incremental build
class	 SignJar	 extends	 DefaultTask	 {

	 	 	 	 @InputFiles	 FileCollection	 jarFiles

	 	 	 	 @OutputDirectory	 File	 outputDir

	 	 	 	 File	 keystore

	 	 	 	 String	 keystorePassword

	 	 	 	 String	 alias

	 	 	 	 String	 aliasPassword

	 	 	 	 @TaskAction

	 	 	 	 void	 sign()	 {

	 	 	 	 	 	 	 	 ...

	 	 	 	 }

}
Changes to these input
files or output force the
task to run again
Plugins
• Encapsulate your conventions
• Package common features
• Lightweight alternative:
- apply	 from:	 "modules/check.gradle"
Know your users
Questions to ask
• Do you have only one type of user?
• What things can each type of user do?
• What do they want from the build?
• What should they see?
Example
compile
test
package/install
publish
project
lead only
Lazybones
project
If the project is published, require credentials
Fail fast
Other users don’t require credentials
Interrogate task graph
gradle.taskGraph.whenReady	 {	 graph	 ->

	 	 	 	 if	 (graph.hasTask(":lazybones-app:uploadDist"))	 {

	 	 	 	 	 	 	 	 verifyProperty(project,	 'repo.url')

	 	 	 	 	 	 	 	 verifyProperty(project,	 'repo.username')

	 	 	 	 	 	 	 	 verifyProperty(project,	 'repo.apiKey')

	 	 	 	 	 	 	 	 uploadDist.repositoryUrl	 =	 project.'repo.url'

	 	 	 	 	 	 	 	 uploadDist.username	 =	 project.'repo.username'

	 	 	 	 	 	 	 	 uploadDist.apiKey	 =	 project.'repo.apiKey'

	 	 	 	 }

}
Only check for credentials if user is trying to
publish:
Only fail fast if `uploadTask` will be executed
Fail slow would require integration tests to run - adding minutes to deployment
Other uses
• Include class obfuscation conditionally
• Limit visibility of tasks based on role
• Update version based on ‘release’ task
Summary
• Understand the Gradle model
• Keep refactoring
• Understand your build
• Know your users
Thank you!
e: peter@cacoethes.co.uk
w: http://www.cacoethes.co.uk
t: @pledbrook

More Related Content

What's hot

Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012Hazem Saleh
 
Managing big test environment and running tests with Jenkins, Jenkins Job bui...
Managing big test environment and running tests with Jenkins, Jenkins Job bui...Managing big test environment and running tests with Jenkins, Jenkins Job bui...
Managing big test environment and running tests with Jenkins, Jenkins Job bui...Timofey Turenko
 
Exploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & BeyondExploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & BeyondKaushal Dhruw
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You TestCool JVM Tools to Help You Test
Cool JVM Tools to Help You TestSchalk Cronjé
 
Modularizing your Grails Application with Private Plugins - SpringOne 2GX 2012
Modularizing your Grails Application with Private Plugins - SpringOne 2GX 2012Modularizing your Grails Application with Private Plugins - SpringOne 2GX 2012
Modularizing your Grails Application with Private Plugins - SpringOne 2GX 2012kennethaliu
 
Continuous Integration using Cruise Control
Continuous Integration using Cruise ControlContinuous Integration using Cruise Control
Continuous Integration using Cruise Controlelliando dias
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionSchalk Cronjé
 
Idiomatic gradle plugin writing
Idiomatic gradle plugin writingIdiomatic gradle plugin writing
Idiomatic gradle plugin writingSchalk Cronjé
 
Dsc Charusat Learning React Part 1
Dsc Charusat Learning React Part 1 Dsc Charusat Learning React Part 1
Dsc Charusat Learning React Part 1 JainamMehta19
 
Introducing Playwright's New Test Runner
Introducing Playwright's New Test RunnerIntroducing Playwright's New Test Runner
Introducing Playwright's New Test RunnerApplitools
 
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers VersionCool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers VersionSchalk Cronjé
 
The Gist of React Native
The Gist of React NativeThe Gist of React Native
The Gist of React NativeDarren Cruse
 
Gradle - Build system evolved
Gradle - Build system evolvedGradle - Build system evolved
Gradle - Build system evolvedBhagwat Kumar
 
Building an Extensible, Resumable DSL on Top of Apache Groovy
Building an Extensible, Resumable DSL on Top of Apache GroovyBuilding an Extensible, Resumable DSL on Top of Apache Groovy
Building an Extensible, Resumable DSL on Top of Apache Groovyjgcloudbees
 
Automated Testing in Angular Slides
Automated Testing in Angular SlidesAutomated Testing in Angular Slides
Automated Testing in Angular SlidesJim Lynch
 
Gradle: The Build System you have been waiting for!
Gradle: The Build System you have been waiting for!Gradle: The Build System you have been waiting for!
Gradle: The Build System you have been waiting for!Corneil du Plessis
 
Lunch and learn: Cucumber and Capybara
Lunch and learn: Cucumber and CapybaraLunch and learn: Cucumber and Capybara
Lunch and learn: Cucumber and CapybaraMarc Seeger
 

What's hot (20)

Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012
 
Managing big test environment and running tests with Jenkins, Jenkins Job bui...
Managing big test environment and running tests with Jenkins, Jenkins Job bui...Managing big test environment and running tests with Jenkins, Jenkins Job bui...
Managing big test environment and running tests with Jenkins, Jenkins Job bui...
 
Exploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & BeyondExploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & Beyond
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You TestCool JVM Tools to Help You Test
Cool JVM Tools to Help You Test
 
Introduction of React.js
Introduction of React.jsIntroduction of React.js
Introduction of React.js
 
Modularizing your Grails Application with Private Plugins - SpringOne 2GX 2012
Modularizing your Grails Application with Private Plugins - SpringOne 2GX 2012Modularizing your Grails Application with Private Plugins - SpringOne 2GX 2012
Modularizing your Grails Application with Private Plugins - SpringOne 2GX 2012
 
Continuous Integration using Cruise Control
Continuous Integration using Cruise ControlContinuous Integration using Cruise Control
Continuous Integration using Cruise Control
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 version
 
Idiomatic gradle plugin writing
Idiomatic gradle plugin writingIdiomatic gradle plugin writing
Idiomatic gradle plugin writing
 
Workshop React.js
Workshop React.jsWorkshop React.js
Workshop React.js
 
Dsc Charusat Learning React Part 1
Dsc Charusat Learning React Part 1 Dsc Charusat Learning React Part 1
Dsc Charusat Learning React Part 1
 
Introducing Playwright's New Test Runner
Introducing Playwright's New Test RunnerIntroducing Playwright's New Test Runner
Introducing Playwright's New Test Runner
 
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers VersionCool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
 
The Gist of React Native
The Gist of React NativeThe Gist of React Native
The Gist of React Native
 
Gradle - Build system evolved
Gradle - Build system evolvedGradle - Build system evolved
Gradle - Build system evolved
 
Building an Extensible, Resumable DSL on Top of Apache Groovy
Building an Extensible, Resumable DSL on Top of Apache GroovyBuilding an Extensible, Resumable DSL on Top of Apache Groovy
Building an Extensible, Resumable DSL on Top of Apache Groovy
 
Automated Testing in Angular Slides
Automated Testing in Angular SlidesAutomated Testing in Angular Slides
Automated Testing in Angular Slides
 
Gradle: The Build System you have been waiting for!
Gradle: The Build System you have been waiting for!Gradle: The Build System you have been waiting for!
Gradle: The Build System you have been waiting for!
 
Lunch and learn: Cucumber and Capybara
Lunch and learn: Cucumber and CapybaraLunch and learn: Cucumber and Capybara
Lunch and learn: Cucumber and Capybara
 
Gradle by Example
Gradle by ExampleGradle by Example
Gradle by Example
 

Similar to Improving your Gradle builds

In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleSkills Matter
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingSchalk Cronjé
 
Faster java ee builds with gradle [con4921]
Faster java ee builds with gradle [con4921]Faster java ee builds with gradle [con4921]
Faster java ee builds with gradle [con4921]Ryan Cuprak
 
Gradle - time for another build
Gradle - time for another buildGradle - time for another build
Gradle - time for another buildIgor Khotin
 
Introduction to Apache Ant
Introduction to Apache AntIntroduction to Apache Ant
Introduction to Apache AntShih-Hsiang Lin
 
Gradle - time for a new build
Gradle - time for a new buildGradle - time for a new build
Gradle - time for a new buildIgor Khotin
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e bigAndy Peterson
 
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with GradleRyan Cuprak
 
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with GradleRyan Cuprak
 
Gradle plugin, take control of the build
Gradle plugin, take control of the buildGradle plugin, take control of the build
Gradle plugin, take control of the buildEyal Lezmy
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingSchalk Cronjé
 
Gradle - small introduction
Gradle - small introductionGradle - small introduction
Gradle - small introductionIgor Popov
 
Gradle: The Build system you have been waiting for
Gradle: The Build system you have been waiting forGradle: The Build system you have been waiting for
Gradle: The Build system you have been waiting forCorneil du Plessis
 
Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Tino Isnich
 

Similar to Improving your Gradle builds (20)

In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: Gradle
 
GradleFX
GradleFXGradleFX
GradleFX
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
Faster java ee builds with gradle [con4921]
Faster java ee builds with gradle [con4921]Faster java ee builds with gradle [con4921]
Faster java ee builds with gradle [con4921]
 
Gradle - time for another build
Gradle - time for another buildGradle - time for another build
Gradle - time for another build
 
Introduction to Apache Ant
Introduction to Apache AntIntroduction to Apache Ant
Introduction to Apache Ant
 
Enter the gradle
Enter the gradleEnter the gradle
Enter the gradle
 
OpenCms Days 2012 - Developing OpenCms with Gradle
OpenCms Days 2012 - Developing OpenCms with GradleOpenCms Days 2012 - Developing OpenCms with Gradle
OpenCms Days 2012 - Developing OpenCms with Gradle
 
Gradle - time for a new build
Gradle - time for a new buildGradle - time for a new build
Gradle - time for a new build
 
Gradle
GradleGradle
Gradle
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
 
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with Gradle
 
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with Gradle
 
Gradle plugin, take control of the build
Gradle plugin, take control of the buildGradle plugin, take control of the build
Gradle plugin, take control of the build
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
Gradle - small introduction
Gradle - small introductionGradle - small introduction
Gradle - small introduction
 
Gradle: The Build system you have been waiting for
Gradle: The Build system you have been waiting forGradle: The Build system you have been waiting for
Gradle: The Build system you have been waiting for
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01
 

More from Peter Ledbrook

Groovy for Java Developers
Groovy for Java DevelopersGroovy for Java Developers
Groovy for Java DevelopersPeter Ledbrook
 
Application Architectures in Grails
Application Architectures in GrailsApplication Architectures in Grails
Application Architectures in GrailsPeter Ledbrook
 
Open source-and-you-gr8conf-us-2013
Open source-and-you-gr8conf-us-2013Open source-and-you-gr8conf-us-2013
Open source-and-you-gr8conf-us-2013Peter Ledbrook
 
Groovy & Grails for Spring/Java developers
Groovy & Grails for Spring/Java developersGroovy & Grails for Spring/Java developers
Groovy & Grails for Spring/Java developersPeter Ledbrook
 
Grails & the World of Tomorrow
Grails & the World of TomorrowGrails & the World of Tomorrow
Grails & the World of TomorrowPeter Ledbrook
 
Migrating to Cloud Foundry
Migrating to Cloud FoundryMigrating to Cloud Foundry
Migrating to Cloud FoundryPeter Ledbrook
 
Grails and the World of Tomorrow
Grails and the World of TomorrowGrails and the World of Tomorrow
Grails and the World of TomorrowPeter Ledbrook
 
Cloud Foundry for Java devs
Cloud Foundry for Java devsCloud Foundry for Java devs
Cloud Foundry for Java devsPeter Ledbrook
 

More from Peter Ledbrook (9)

Groovy for Java Developers
Groovy for Java DevelopersGroovy for Java Developers
Groovy for Java Developers
 
Application Architectures in Grails
Application Architectures in GrailsApplication Architectures in Grails
Application Architectures in Grails
 
Open source-and-you-gr8conf-us-2013
Open source-and-you-gr8conf-us-2013Open source-and-you-gr8conf-us-2013
Open source-and-you-gr8conf-us-2013
 
Groovy & Grails for Spring/Java developers
Groovy & Grails for Spring/Java developersGroovy & Grails for Spring/Java developers
Groovy & Grails for Spring/Java developers
 
Grails & the World of Tomorrow
Grails & the World of TomorrowGrails & the World of Tomorrow
Grails & the World of Tomorrow
 
Migrating to Cloud Foundry
Migrating to Cloud FoundryMigrating to Cloud Foundry
Migrating to Cloud Foundry
 
Grails 2.0 Update
Grails 2.0 UpdateGrails 2.0 Update
Grails 2.0 Update
 
Grails and the World of Tomorrow
Grails and the World of TomorrowGrails and the World of Tomorrow
Grails and the World of Tomorrow
 
Cloud Foundry for Java devs
Cloud Foundry for Java devsCloud Foundry for Java devs
Cloud Foundry for Java devs
 

Recently uploaded

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 

Recently uploaded (20)

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

Improving your Gradle builds

  • 1. Improving your Gradle builds Peter Ledbrook e: peter@cacoethes.co.uk w: http://www.cacoethes.co.uk t: @pledbrook
  • 2. “Safety” in build tools "Straight Razor" by Horst.Burkhardt - Own work. Licensed under CC BY-SA 3.0 via Wikimedia Commons Gradle is often treated like a cut-throat razor: unsafe Code == spaghetti builds (allegedly) Some people think it’s better to limit build authors to configuration only Is this a good comparison though?
  • 3. A better analogy by Noel C. Hankamer - Creative Commons 2.0 Not all jobs are the same for a workman Need the right tools for the job Some tools are dangerous - so you learn to use them Power drills, heavy duty knives, etc.
  • 4. Gradle Yes, you can create spaghetti builds, but… “A bad workman blames his tools”
  • 5. So how do you create maintainable builds?
  • 6. First, understand the Gradle model
  • 7. Gradle is an API Project Task Repository Dependency Configuration Source set (Java) This is just part of the Gradle model, which allows you to model your own build processes. Show Gradle DSL and API references if possible: http://www.gradle.org/doc/latest/…
  • 8. A basic Java build apply plugin: "java" version = "1.0" repositories { jcenter() } dependencies { compile "asm:asm-all:3.3.1", "commons-io:commons-io:1.4" } compileJava.options.incremental = true An instance of Task A Repository
  • 9. Everything from Project • project.tasks • project.configurations • project.repositories • project.dependencies • project.sourceSets (added by Java plugin) All the model elements are available from the project The project itself can be accessed via the `project` property
  • 10. The three phases Initialisation Configuration Execution Only relevant to multi- project builds Configures tasks and builds the task graph Executes the necessary tasks based on the task graph Beyond the model that defines the build, this is what happens when you actually run that build
  • 11. At execution Y X Z => Z X Y W V Linear execution orderTask graph W V During configuration Gradle builds a Directed Acyclic Graph (DAG) of tasks Before execution, the graph is turned into an execution order There is no distinction between targets and tasks like in Apache Ant
  • 14. Beware the config phase • Configuration always happens - even just running grade tasks! - this will change soon(ish) • Avoid expensive work
  • 15. Profile your build! gradle --profile <taskName> This generates a report with timings for the different phases of each project in the build
  • 16.
  • 17. Example apply plugin: "java" ... jar { version = new URL("http://buildsvr/version").text } Evaluated every build! (This will change soon in Gradle) Potentially unreliable network call *every* time the build runs No matter what tasks are executed Gradle will perform configuration on-demand in the not too distant future, reducing the time cost of the configuration phase
  • 18. Remember task doSomething << { println "Doing it!" } task customJar(type: Jar) { archivePath = customJarPath doLast { println "Created the JAR file" } } Execution Execution Configuration Consider always using `doLast()` instead of `<<` to avoid confusion between configuration and implicit execution
  • 20. Project properties • Useful for build parameterisation • Equivalent to global variables - Same problems! • Provide sensible defaults • Assume values are strings
  • 21. Default values ext { jarFilename = project.hasProperty("jarFilename") ? jarFilename : "myArchive" } task customJar(type: Jar) { archivePath = file("$buildDir/$jarFilename") doLast { println "Created the JAR file: ${archivePath}" } } Check property exists first Default value Values can be overridden via -P cmd line option gradle.properties Both only support strings
  • 22. Prefer task properties task customClean(type: Delete) { delete "$buildDir/$jarFilename" } task customClean(type: Delete) { delete customJar.archivePath } Use the path defined by the task Don’t let project properties litter your build If the JAR task stops using the project property, `customClean` will continue to work
  • 24. Custom tasks Prefer task doIt(type: MyTask) class MyTask extends DefaultTask { @TaskAction def action() { println "Hello world!" } } task doIt << { println "Hello world!" } } over More verbose, but easier to maintain Easier to incorporate properties in custom task classes Easier to migrate the task implementation out of the build file
  • 25. Custom tasks Where the task class goes: 1. In build.gradle 2. In buildSrc/src/groovy/… 3. In a JAR file
  • 26. IoC in tasks class MyTask extends DefaultTask { File filePath = project.myArchivePath @TaskAction def action() { println filePath.text } } Don’t pull values from the environment
  • 27. IoC in tasks task doIt(type: MyTask) { filePath = project.myArchivePath } Leave configuration in the build file Effectively Inversion of Control - values should always be injected
  • 28. Last one… Consider breaking into multiple smaller projects
  • 30. Task order vs dependency task functionalTest(type: Test, dependsOn: test) task functionalTest(type: Test) { mustRunAfter test } Do the functional tests require the unit tests to run? Or is it just the order that counts?
  • 31. Leverage source sets Instead of configurations { clientCompile } task compileClient(type: JavaCompile) { classpath ... include "src/main/java/**/client/*" } // Don't forget the test tasks and dependencies! ...
  • 32. Leverage source sets Use source sets sourceSets { client { java { srcDirs file("src/main/java") include "src/main/java/**/client/*" } } } Get: • clientCompile, clientRuntime configurations • compileClientJava task
  • 33. Use incremental build class SignJar extends DefaultTask { @InputFiles FileCollection jarFiles @OutputDirectory File outputDir File keystore String keystorePassword String alias String aliasPassword @TaskAction void sign() { ... } } Changes to these input files or output force the task to run again
  • 34. Plugins • Encapsulate your conventions • Package common features • Lightweight alternative: - apply from: "modules/check.gradle"
  • 36. Questions to ask • Do you have only one type of user? • What things can each type of user do? • What do they want from the build? • What should they see?
  • 37. Example compile test package/install publish project lead only Lazybones project If the project is published, require credentials Fail fast Other users don’t require credentials
  • 38. Interrogate task graph gradle.taskGraph.whenReady { graph -> if (graph.hasTask(":lazybones-app:uploadDist")) { verifyProperty(project, 'repo.url') verifyProperty(project, 'repo.username') verifyProperty(project, 'repo.apiKey') uploadDist.repositoryUrl = project.'repo.url' uploadDist.username = project.'repo.username' uploadDist.apiKey = project.'repo.apiKey' } } Only check for credentials if user is trying to publish: Only fail fast if `uploadTask` will be executed Fail slow would require integration tests to run - adding minutes to deployment
  • 39. Other uses • Include class obfuscation conditionally • Limit visibility of tasks based on role • Update version based on ‘release’ task
  • 40. Summary • Understand the Gradle model • Keep refactoring • Understand your build • Know your users
  • 41. Thank you! e: peter@cacoethes.co.uk w: http://www.cacoethes.co.uk t: @pledbrook