SlideShare a Scribd company logo
ANDRES ALMIRAY
@AALMIRAY
MAKING THE MOST OF
YOUR GRADLE BUILD
Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017
1
HOW TO GET GRADLE
INSTALLED ON YOUR
SYSTEM
$ curl -s get.sdkman.io | bash
$ sdk install gradle
2
INITIALIZING A GRADLE
PROJECT
GRADLE INIT
THIS COMMAND WILL GENERATE A BASIC STRUCTURE
AND A MINIMUM SET OF FILES TO GET STARTED.
YOU CAN INVOKE THIS COMMAND ON A MAVEN PROJECT
TO TURN IT INTO A GRADLE PROJECT. MUST MIGRATE
PLUGINS MANUALLY.
$ sdk install lazybones
$ lazybones create gradle-quickstart
sample
3
FIX GRADLE VERSION TO A
PARTICULAR RELEASE
GRADLE WRAPPER
INITIALIZE THE WRAPPER WITH A GIVEN VERSION.
CHANGE FROM –bin.zip TO –all.zip TO HAVE ACCESS TO
GRADLE API SOURCES.
4
INVOKING GRADLE
ANYWHERE ON YOUR
PROJECT
GDUB
https://github.com/dougborg/gdub
A SCRIPT THAT CAN INVOKE A GRADLE BUILD ANYWHERE
INSIDE THE PROJECT STRUCTURE.
WILL ATTEMPT RESOLVING WRAPPER FIRST, THEN LOCAL
GRADLE.
FAILS IF NEITHER IS FOUND.
5
MULTI-PROJECT SETUP
CHANGE BUILD FILE NAMES
CHANGE BULD FILE NAME FROM build.gradle TO
${project.name}.gradle
USE GROOVY EXPRESSIONS TO FACTORIZE PROJECT
INCLUSIONS IN settings.gradle
SETTINGS.GRADLE (1/2)
['common',	
  'full',	
  'light'].each	
  {	
  name	
  -­‐>	
  
	
  	
  	
  	
  File	
  subdir	
  =	
  new	
  File(rootDir,	
  name)	
  
	
  	
  	
  	
  subdir.eachDir	
  {	
  dir	
  -­‐>	
  
	
  	
  	
  	
  	
  	
  	
  	
  File	
  buildFile	
  =	
  new	
  File(dir,	
  "${dir.name}.gradle")	
  
	
  	
  	
  	
  	
  	
  	
  	
  if	
  (buildFile.exists())	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  include	
  "${name}/${dir.name}"	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  
}	
  
SETTINGS.GRADLE (2/2)
rootProject.name	
  =	
  'my-­‐project'	
  
rootProject.children.each	
  {	
  project	
  -­‐>	
  
	
  	
  	
  	
  int	
  slash	
  =	
  project.name.indexOf('/')	
  
	
  	
  	
  	
  String	
  fileBaseName	
  =	
  project.name[(slash	
  +	
  1)..-­‐1]	
  
	
  	
  	
  	
  String	
  projectDirName	
  =	
  project.name	
  
	
  	
  	
  	
  project.name	
  =	
  fileBaseName	
  
	
  	
  	
  	
  project.projectDir	
  =	
  new	
  File(settingsDir,	
  projectDirName)	
  
	
  	
  	
  	
  project.buildFileName	
  =	
  "${fileBaseName}.gradle"	
  
	
  	
  	
  	
  assert	
  project.projectDir.isDirectory()	
  
	
  	
  	
  	
  assert	
  project.buildFile.isFile()	
  
}	
  
6
BUILD FILE ETIQUETTE
WHAT BUILD.GRADLE IS NOT
KEEP IT DRY
EMBRACE THE POWER OF CONVENTIONS.
BUILD FILE SHOULD DEFINE HOW THE PROJECT DEVIATES
FROM THE PRE-ESTABLISHED CONVENTIONS.
RELY ON SECONDARY SCRIPTS, SEGGREGATED BY
RESPONSIBILITIES.
TASK DEFINITIONS
PUT THEM IN SEPARATE FILES.
1.  INSIDE SECONDARY SCRIPTS
1.  REGULAR TASK DEFINITIONS
2.  PLUGIN DEFINITIONS
2.  AS PART OF buildSrc SOURCES
3.  AS A PLUGIN PROJECT
APPLYING PLUGINS
USE THE PLUGINS BLOCK DSL IF IN A SINGLE PROJECT.
PLUGINS BLOCK DOES NOT WORK IN SECONDARY
SCRIPTS.
USE THE OLD-SCHOOL SYNTAX IF IN A MULTI-PROJECT
AND NOT ALL SUBPROJECTS REQUIRE THE SAME
PLUGINS.
7
DON’T REINVENT THE
WHEEL, APPLY PLUGINS
INSTEAD
Making the most of your gradle build - Greach 2017
USEFUL PLUGINS
Versions
id 'com.github.ben-manes.versions' version '0.14.0’
License
id 'com.github.hierynomus.license' version '0.11.0’
Versioning
id 'net.nemerosa.versioning' version '2.6.0'
FILTERING VERSIONS
apply	
  plugin:	
  'com.github.ben-­‐manes.versions'	
  
dependencyUpdates.resolutionStrategy	
  =	
  {	
  
	
  	
  	
  	
  componentSelection	
  {	
  rules	
  -­‐>	
  
	
  	
  	
  	
  	
  	
  	
  	
  rules.all	
  {	
  selection	
  -­‐>	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  boolean	
  rejected	
  =	
  ['alpha',	
  'beta',	
  'rc’].any	
  {	
  qualifier	
  -­‐>	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  selection.candidate.version	
  ==~	
  /(?i).*[.-­‐]${qualifier}[.d-­‐]*/	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  if	
  (rejected)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  selection.reject('Release	
  candidate')	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  
}	
  
8
KEEP ALL VERSIONS IN ONE
PLACE
IN GRADLE.PROPERTIES (1)
awaitilityVersion	
  	
  =	
  2.0.0	
  
bootstrapfxVersion	
  =	
  0.2.1	
  
guiceVersion	
  	
  	
  	
  	
  	
  	
  =	
  4.1.0	
  
hamcrestVersion	
  	
  	
  	
  =	
  1.3	
  
ikonliVersion	
  	
  	
  	
  	
  	
  =	
  1.9.0	
  
jacksonVersion	
  	
  	
  	
  	
  =	
  2.8.7	
  
jdeferredVersion	
  	
  	
  =	
  1.2.5	
  
jukitoVersion	
  	
  	
  	
  	
  	
  =	
  1.5	
  
junitVersion	
  	
  	
  	
  	
  	
  	
  =	
  4.12	
  
lombokVersion	
  	
  	
  	
  	
  	
  =	
  1.16.16	
  
mbassadorVersion	
  	
  	
  =	
  1.3.0	
  
miglayoutVersion	
  	
  	
  =	
  5.0	
  
mockitoVersion	
  	
  	
  	
  	
  =	
  2.7.19	
  
reactfxVersion	
  	
  	
  	
  	
  =	
  2.0-­‐M5	
  
retrofitVersion	
  	
  	
  	
  =	
  2.2.0	
  
slf4jVersion	
  	
  	
  	
  	
  	
  	
  =	
  1.7.25	
  
testfxVersion	
  	
  	
  	
  	
  	
  =	
  4.0.6-­‐alpha	
  
wiremockVersion	
  	
  	
  	
  =	
  2.5.1	
  
IN BUILD.GRADLE (2)
dependencies	
  {	
  
	
  	
  	
  	
  compile	
  "net.engio:mbassador:$mbassadorVersion"	
  
	
  	
  	
  	
  compile	
  "org.reactfx:reactfx:$reactfxVersion"	
  
	
  	
  	
  	
  compile	
  "org.slf4j:slf4j-­‐api:$slf4jVersion"	
  
	
  	
  	
  	
  compile	
  "org.jdeferred:jdeferred-­‐core:$jdeferredVersion"	
  
	
  	
  	
  	
  compile	
  "com.squareup.retrofit2:retrofit:$retrofitVersion"	
  
	
  	
  	
  	
  compile	
  "com.squareup.retrofit2:converter-­‐jackson:$retrofitVersion"	
  
	
  	
  	
  	
  compile	
  "com.fasterxml.jackson.core:jackson-­‐core:$jacksonVersion"	
  
	
  	
  	
  	
  compile	
  "com.fasterxml.jackson.core:jackson-­‐annotations:$jacksonVersion"	
  
	
  	
  	
  	
  compile	
  "com.fasterxml.jackson.core:jackson-­‐databind:$jacksonVersion"	
  
	
  	
  	
  	
  /*	
  and	
  more	
  ...	
  */	
  
}	
  
9
DEPENDENCY VERSIONS
CONVERGENCE
FORCE VERSIONS AND CHECK
configurations.all	
  {	
  
	
  	
  	
  	
  resolutionStrategy.force	
  "jdepend:jdepend:$jdependVersion",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "com.google.guava:guava:$guavaVersion",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "junit:junit:$junitVersion",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "cglib:cglib-­‐nodep:$cglibVersion",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "org.asciidoctor:asciidoctorj:$asciidoctorjVersion",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "org.codehau.groovy:groovy-­‐all:$groovyVersion",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "org.slf4j:slf4j-­‐api:$slf4jVersion",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "org.slf4j:slf4j-­‐simple:$slf4jVersion",	
  
	
  	
  	
  	
  	
  	
  	
  	
  "org.easytesting:fest-­‐util:$festUtilVersion"	
  
	
  
	
  	
  	
  	
  resolutionStrategy.failOnVersionConflict()	
  
}	
  
10
SUPPLY MORE INFORMATION
TO DEVELOPERS
MANIFEST ENTRIES
ENRICH JAR MANIFESTS WITH ADDITIONAL ENTRIES SUCH AS
'Built-By': System.properties['user.name'],
'Created-By': "${System.properties['java.version']} (${System.properties['java.vendor']}
${System.properties['java.vm.version']})".toString(),
'Build-Date': buildDate,
'Build-Time': buildTime,
'Build-Revision': versioning.info.commit,
'Specification-Title': project.name,
'Specification-Version': project.version,
'Specification-Vendor': project.vendor,
'Implementation-Title': project.name,
'Implementation-Version': project.version,
'Implementation-Vendor': project.vendor
11
INCREMENTAL BUILDS
INCREMENTAL BUILD
ACTIVATED BY ADDING –t TO THE COMMAND LINE.
EXECUTES A GIVEN COMMAND WHENEVER ITS
RESOURCES (INPUTS) CHANGE.
AVOID INVOKING THE CLEAN TASK AS MUCH AS YOU CAN.
12
AGGREGATE CODE
COVERAGE REPORTS
JACOCO OR BUST
STEP 1: DEFINE A LIST OF PROJECTS TO INCLUDE
ext	
  {	
  
	
  	
  	
  	
  projectsWithCoverage	
  =	
  []	
  
	
  	
  	
  	
  baseJaCocoDir	
  =	
  "${buildDir}/reports/jacoco/test/"	
  
	
  	
  	
  	
  jacocoMergeExecFile	
  =	
  "${baseJaCocoDir	
  }jacocoTestReport.exec"	
  
	
  	
  	
  	
  jacocoMergeReportHTMLFile	
  =	
  "${baseJaCocoDir	
  }/html/"	
  
	
  	
  	
  	
  jacocoMergeReportXMLFile	
  =	
  "${baseJaCocoDir}/jacocoTestReport.xml"	
  
}	
  
JACOCO OR BUST
STEP 2: ADD PROJECT TO COVERAGE LIST
jacocoTestReport	
  {	
  
	
  	
  	
  	
  group	
  =	
  'Reporting'	
  
	
  	
  	
  	
  description	
  =	
  'Generate	
  Jacoco	
  coverage	
  reports	
  after	
  running	
  tests.'	
  
	
  	
  	
  	
  additionalSourceDirs	
  =	
  project.files(sourceSets.main.allSource.srcDirs)	
  
	
  	
  	
  	
  sourceDirectories	
  =	
  project.files(sourceSets.main.allSource.srcDirs)	
  
	
  	
  	
  	
  classDirectories	
  =	
  project.files(sourceSets.main.output)	
  
	
  	
  	
  	
  reports	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  xml.enabled	
  =	
  true	
  
	
  	
  	
  	
  	
  	
  	
  	
  csv.enabled	
  =	
  false	
  
	
  	
  	
  	
  	
  	
  	
  	
  html.enabled	
  =	
  true	
  
	
  	
  	
  	
  }	
  
}	
  
projectsWithCoverage	
  <<	
  project	
  
JACOCO OR BUST
STEP 3: DEFINE AGGREGATE TASKS IN ROOT PROJECT
evaluationDependsOnChildren()	
  //	
  VERY	
  IMPORTANT!!	
  
	
  
task	
  jacocoRootMerge(type:	
  org.gradle.testing.jacoco.tasks.JacocoMerge)	
  {	
  
	
  	
  	
  	
  dependsOn	
  =	
  projectsWithCoverage.test	
  +	
  
projectsWithCoverage.jacocoTestReport	
  	
  
	
  	
  	
  	
  executionData	
  =	
  projectsWithCoverage.jacocoTestReport.executionData	
  
	
  	
  	
  	
  destinationFile	
  =	
  file(jacocoMergeExecFile)	
  
}	
  
JACOCO OR BUST
STEP 3: DEFINE AGGREGATE TASKS IN ROOT PROJECT
task	
  jacocoRootMergeReport(dependsOn:	
  jacocoRootMerge,	
  type:	
  JacocoReport)	
  {	
  
	
  	
  	
  	
  executionData	
  projectsWithCoverage.jacocoTestReport.executionData	
  
	
  	
  	
  	
  sourceDirectories	
  =	
  projectsWithCoverage.sourceSets.main.allSource.srcDirs	
  
	
  	
  	
  	
  classDirectories	
  =	
  projectsWithCoverage.sourceSets.main.output	
  
	
  
	
  	
  	
  	
  reports	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  html.enabled	
  =	
  true	
  
	
  	
  	
  	
  	
  	
  	
  	
  xml.enabled	
  =	
  true	
  
	
  	
  	
  	
  	
  	
  	
  	
  html.destination	
  =	
  file(jacocoMergeReportHTMLFile)	
  
	
  	
  	
  	
  	
  	
  	
  	
  xml.destination	
  =	
  file(jacocoMergeReportXMLFile)	
  
	
  	
  	
  	
  }	
  
}	
  
13
MIND THE TARGET JAVA
VERSION
JDK8 VS JDK7
JOINT COMPILING GROOVY CODE MAY GIVE YOU HEADACHES IF
THE SOURCE/TARGET COMPATIBILITY IS NOT SET RIGHT
	
  
tasks.withType(JavaCompile)	
  {	
  t	
  -­‐>	
  
	
  	
  	
  	
  t.sourceCompatibility	
  =	
  project.sourceCompatibility	
  
	
  	
  	
  	
  t.targetCompatibility	
  =	
  project.targetCompatibility	
  
}	
  
	
  
tasks.withType(GroovyCompile)	
  {	
  t	
  -­‐>	
  
	
  	
  	
  	
  t.sourceCompatibility	
  =	
  project.sourceCompatibility	
  
	
  	
  	
  	
  t.targetCompatibility	
  =	
  project.targetCompatibility	
  
}	
  
JDK8 JAVADOC TROUBLES
JAVADOC IN JDK8 IS VERY PEDANTIC
	
  
if	
  (JavaVersion.current().isJava8Compatible())	
  {	
  
	
  	
  	
  	
  tasks.withType(Javadoc)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  options.addStringOption('Xdoclint:none',	
  '-­‐quiet')	
  
	
  	
  	
  	
  }	
  
}	
  
COMPILE WARNINGS
ACTIVATE COMPILER WARNINGS AT WILL
	
  
tasks.withType(AbstractCompile)	
  {	
  
	
  	
  	
  	
  if	
  (rootProject.hasProperty('lint')	
  &&	
  rootProject.lint.toBoolean())	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  options.compilerArgs	
  =	
  [	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  '-­‐Xlint:all',	
  '-­‐Xlint:deprecation',	
  '-­‐Xlint:unchecked'	
  
	
  	
  	
  	
  	
  	
  	
  	
  ]	
  
	
  	
  	
  	
  }	
  
}	
  
	
  
$	
  ./gradlew	
  –Plint=true	
  compile	
  
14
PLUGINS! PLUGINS!
PLUGINS!
license
versions
stats
bintray
shadow
izpack
java2html
git
coveralls
asciidoctor
jbake
markdown
livereload
gretty
nexus
watch
apt
spawn
versioning
pitest
build-time-tracker
semantic-release
clirr
japicmp
compass
flyway
jmh
macappbundle
osspackage
jnlp
spotless
dependency-
management
sshoogr
THANK YOU!
ANDRES ALMIRAY
@AALMIRAY

More Related Content

PDF
Testing Java Code Effectively
Andres Almiray
 
PPTX
Java Libraries You Can’t Afford to Miss
Andres Almiray
 
PDF
Java Libraries You Can’t Afford to Miss
Andres Almiray
 
PDF
Making the Most of Your Gradle Build
Andres Almiray
 
PDF
Making the Most of Your Gradle Build
Andres Almiray
 
PDF
The JavaFX Ecosystem
Andres Almiray
 
PDF
Android Design Patterns
Godfrey Nolan
 
PDF
Java8 tgtbatu javaone
Brian Vermeer
 
Testing Java Code Effectively
Andres Almiray
 
Java Libraries You Can’t Afford to Miss
Andres Almiray
 
Java Libraries You Can’t Afford to Miss
Andres Almiray
 
Making the Most of Your Gradle Build
Andres Almiray
 
Making the Most of Your Gradle Build
Andres Almiray
 
The JavaFX Ecosystem
Andres Almiray
 
Android Design Patterns
Godfrey Nolan
 
Java8 tgtbatu javaone
Brian Vermeer
 

What's hot (20)

PDF
Agile Android
Godfrey Nolan
 
PDF
iOS Behavior-Driven Development
Brian Gesiak
 
PDF
Java(8) The Good, The Bad and the Ugly
Brian Vermeer
 
PDF
GeeCON 2017 - TestContainers. Integration testing without the hassle
Anton Arhipov
 
PDF
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Schalk Cronjé
 
PDF
Android TDD
Godfrey Nolan
 
PDF
Why Kotlin - Apalon Kotlin Sprint Part 1
Kirill Rozov
 
PDF
Redux for ReactJS Programmers
David Rodenas
 
PDF
Gradle talk, Javarsovia 2010
Tomek Kaczanowski
 
PDF
Agile Swift
Godfrey Nolan
 
PDF
Using the Groovy Ecosystem for Rapid JVM Development
Schalk Cronjé
 
PDF
RSpec 3.0: Under the Covers
Brian Gesiak
 
PPTX
Spring & Hibernate
Jiayun Zhou
 
PDF
Java libraries you can't afford to miss
Andres Almiray
 
PDF
Java8 tgtbatu devoxxuk18
Brian Vermeer
 
PDF
Apple Templates Considered Harmful
Brian Gesiak
 
PDF
Springを用いた社内ライブラリ開発
Recruit Lifestyle Co., Ltd.
 
PDF
Java Bytecode for Discriminating Developers - JavaZone 2011
Anton Arhipov
 
PDF
Under the Hood: Using Spring in Grails
GR8Conf
 
PDF
Arquillian Constellation
Alex Soto
 
Agile Android
Godfrey Nolan
 
iOS Behavior-Driven Development
Brian Gesiak
 
Java(8) The Good, The Bad and the Ugly
Brian Vermeer
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
Anton Arhipov
 
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Schalk Cronjé
 
Android TDD
Godfrey Nolan
 
Why Kotlin - Apalon Kotlin Sprint Part 1
Kirill Rozov
 
Redux for ReactJS Programmers
David Rodenas
 
Gradle talk, Javarsovia 2010
Tomek Kaczanowski
 
Agile Swift
Godfrey Nolan
 
Using the Groovy Ecosystem for Rapid JVM Development
Schalk Cronjé
 
RSpec 3.0: Under the Covers
Brian Gesiak
 
Spring & Hibernate
Jiayun Zhou
 
Java libraries you can't afford to miss
Andres Almiray
 
Java8 tgtbatu devoxxuk18
Brian Vermeer
 
Apple Templates Considered Harmful
Brian Gesiak
 
Springを用いた社内ライブラリ開発
Recruit Lifestyle Co., Ltd.
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Anton Arhipov
 
Under the Hood: Using Spring in Grails
GR8Conf
 
Arquillian Constellation
Alex Soto
 
Ad

Similar to Making the most of your gradle build - Greach 2017 (20)

PDF
Making the most of your gradle build - BaselOne 2017
Andres Almiray
 
PDF
Making the most of your gradle build - vJUG24 2017
Andres Almiray
 
PDF
In the Brain of Hans Dockter: Gradle
Skills Matter
 
PDF
Gradle Introduction
Dmitry Buzdin
 
PDF
Gradleintroduction 111010130329-phpapp01
Tino Isnich
 
PDF
Gradle - the Enterprise Automation Tool
Izzet Mustafaiev
 
PDF
Gradle - Build system evolved
Bhagwat Kumar
 
PDF
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Rajmahendra Hegde
 
PPTX
Faster Java EE Builds with Gradle
Ryan Cuprak
 
PPTX
Faster Java EE Builds with Gradle
Ryan Cuprak
 
PDF
Improving your Gradle builds
Peter Ledbrook
 
PDF
Enter the gradle
Parameswari Ettiappan
 
PPTX
Faster java ee builds with gradle [con4921]
Ryan Cuprak
 
PDF
Why your build matters
Peter Ledbrook
 
PDF
Keeping your build tool updated in a multi repository world
Roberto Pérez Alcolea
 
PDF
Gradle - time for a new build
Igor Khotin
 
PPTX
GradleFX
Christophe Herreman
 
PDF
10 Cool Facts about Gradle
Evgeny Goldin
 
PDF
Android gradle-build-system-overview
Kevin He
 
Making the most of your gradle build - BaselOne 2017
Andres Almiray
 
Making the most of your gradle build - vJUG24 2017
Andres Almiray
 
In the Brain of Hans Dockter: Gradle
Skills Matter
 
Gradle Introduction
Dmitry Buzdin
 
Gradleintroduction 111010130329-phpapp01
Tino Isnich
 
Gradle - the Enterprise Automation Tool
Izzet Mustafaiev
 
Gradle - Build system evolved
Bhagwat Kumar
 
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Rajmahendra Hegde
 
Faster Java EE Builds with Gradle
Ryan Cuprak
 
Faster Java EE Builds with Gradle
Ryan Cuprak
 
Improving your Gradle builds
Peter Ledbrook
 
Enter the gradle
Parameswari Ettiappan
 
Faster java ee builds with gradle [con4921]
Ryan Cuprak
 
Why your build matters
Peter Ledbrook
 
Keeping your build tool updated in a multi repository world
Roberto Pérez Alcolea
 
Gradle - time for a new build
Igor Khotin
 
10 Cool Facts about Gradle
Evgeny Goldin
 
Android gradle-build-system-overview
Kevin He
 
Ad

More from Andres Almiray (20)

PDF
Dealing with JSON in the relational world
Andres Almiray
 
PDF
Deploying to production with confidence 🚀
Andres Almiray
 
PDF
Going beyond ORMs with JSON Relational Duality Views
Andres Almiray
 
PDF
Setting up data driven tests with Java tools
Andres Almiray
 
PDF
Creando, creciendo, y manteniendo una comunidad de codigo abierto
Andres Almiray
 
PDF
Liberando a produccion con confianza
Andres Almiray
 
PDF
Liberando a produccion con confidencia
Andres Almiray
 
PDF
OracleDB Ecosystem for Java Developers
Andres Almiray
 
PDF
Softcon.ph - Maven Puzzlers
Andres Almiray
 
PDF
Maven Puzzlers
Andres Almiray
 
PDF
Oracle Database Ecosystem for Java Developers
Andres Almiray
 
PDF
JReleaser - Releasing at the speed of light
Andres Almiray
 
PDF
Building modular applications with the Java Platform Module System and Layrry
Andres Almiray
 
PDF
Going Reactive with g rpc
Andres Almiray
 
PDF
Building modular applications with JPMS and Layrry
Andres Almiray
 
PDF
Taking Micronaut out for a spin
Andres Almiray
 
PDF
Apache Groovy's Metaprogramming Options and You
Andres Almiray
 
PDF
What I wish I knew about Maven years ago
Andres Almiray
 
PDF
What I wish I knew about maven years ago
Andres Almiray
 
PDF
The impact of sci fi in tech
Andres Almiray
 
Dealing with JSON in the relational world
Andres Almiray
 
Deploying to production with confidence 🚀
Andres Almiray
 
Going beyond ORMs with JSON Relational Duality Views
Andres Almiray
 
Setting up data driven tests with Java tools
Andres Almiray
 
Creando, creciendo, y manteniendo una comunidad de codigo abierto
Andres Almiray
 
Liberando a produccion con confianza
Andres Almiray
 
Liberando a produccion con confidencia
Andres Almiray
 
OracleDB Ecosystem for Java Developers
Andres Almiray
 
Softcon.ph - Maven Puzzlers
Andres Almiray
 
Maven Puzzlers
Andres Almiray
 
Oracle Database Ecosystem for Java Developers
Andres Almiray
 
JReleaser - Releasing at the speed of light
Andres Almiray
 
Building modular applications with the Java Platform Module System and Layrry
Andres Almiray
 
Going Reactive with g rpc
Andres Almiray
 
Building modular applications with JPMS and Layrry
Andres Almiray
 
Taking Micronaut out for a spin
Andres Almiray
 
Apache Groovy's Metaprogramming Options and You
Andres Almiray
 
What I wish I knew about Maven years ago
Andres Almiray
 
What I wish I knew about maven years ago
Andres Almiray
 
The impact of sci fi in tech
Andres Almiray
 

Recently uploaded (20)

PDF
Get More from Fiori Automation - What’s New, What Works, and What’s Next.pdf
Precisely
 
PPTX
Agile Chennai 18-19 July 2025 | Emerging patterns in Agentic AI by Bharani Su...
AgileNetwork
 
PDF
The Future of Artificial Intelligence (AI)
Mukul
 
PDF
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
 
PDF
Software Development Methodologies in 2025
KodekX
 
PDF
Doc9.....................................
SofiaCollazos
 
PDF
Accelerating Oracle Database 23ai Troubleshooting with Oracle AHF Fleet Insig...
Sandesh Rao
 
PDF
The Future of Mobile Is Context-Aware—Are You Ready?
iProgrammer Solutions Private Limited
 
PPTX
AI in Daily Life: How Artificial Intelligence Helps Us Every Day
vanshrpatil7
 
PDF
Oracle AI Vector Search- Getting Started and what's new in 2025- AIOUG Yatra ...
Sandesh Rao
 
PPTX
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
PDF
MASTERDECK GRAPHSUMMIT SYDNEY (Public).pdf
Neo4j
 
PDF
How ETL Control Logic Keeps Your Pipelines Safe and Reliable.pdf
Stryv Solutions Pvt. Ltd.
 
PDF
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
PDF
Presentation about Hardware and Software in Computer
snehamodhawadiya
 
PPTX
Simple and concise overview about Quantum computing..pptx
mughal641
 
PDF
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
 
PDF
GDG Cloud Munich - Intro - Luiz Carneiro - #BuildWithAI - July - Abdel.pdf
Luiz Carneiro
 
PDF
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
PPTX
OA presentation.pptx OA presentation.pptx
pateldhruv002338
 
Get More from Fiori Automation - What’s New, What Works, and What’s Next.pdf
Precisely
 
Agile Chennai 18-19 July 2025 | Emerging patterns in Agentic AI by Bharani Su...
AgileNetwork
 
The Future of Artificial Intelligence (AI)
Mukul
 
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
 
Software Development Methodologies in 2025
KodekX
 
Doc9.....................................
SofiaCollazos
 
Accelerating Oracle Database 23ai Troubleshooting with Oracle AHF Fleet Insig...
Sandesh Rao
 
The Future of Mobile Is Context-Aware—Are You Ready?
iProgrammer Solutions Private Limited
 
AI in Daily Life: How Artificial Intelligence Helps Us Every Day
vanshrpatil7
 
Oracle AI Vector Search- Getting Started and what's new in 2025- AIOUG Yatra ...
Sandesh Rao
 
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
MASTERDECK GRAPHSUMMIT SYDNEY (Public).pdf
Neo4j
 
How ETL Control Logic Keeps Your Pipelines Safe and Reliable.pdf
Stryv Solutions Pvt. Ltd.
 
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
Presentation about Hardware and Software in Computer
snehamodhawadiya
 
Simple and concise overview about Quantum computing..pptx
mughal641
 
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
 
GDG Cloud Munich - Intro - Luiz Carneiro - #BuildWithAI - July - Abdel.pdf
Luiz Carneiro
 
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
OA presentation.pptx OA presentation.pptx
pateldhruv002338
 

Making the most of your gradle build - Greach 2017

  • 1. ANDRES ALMIRAY @AALMIRAY MAKING THE MOST OF YOUR GRADLE BUILD
  • 4. 1 HOW TO GET GRADLE INSTALLED ON YOUR SYSTEM
  • 5. $ curl -s get.sdkman.io | bash $ sdk install gradle
  • 7. GRADLE INIT THIS COMMAND WILL GENERATE A BASIC STRUCTURE AND A MINIMUM SET OF FILES TO GET STARTED. YOU CAN INVOKE THIS COMMAND ON A MAVEN PROJECT TO TURN IT INTO A GRADLE PROJECT. MUST MIGRATE PLUGINS MANUALLY.
  • 8. $ sdk install lazybones $ lazybones create gradle-quickstart sample
  • 9. 3 FIX GRADLE VERSION TO A PARTICULAR RELEASE
  • 10. GRADLE WRAPPER INITIALIZE THE WRAPPER WITH A GIVEN VERSION. CHANGE FROM –bin.zip TO –all.zip TO HAVE ACCESS TO GRADLE API SOURCES.
  • 12. GDUB https://github.com/dougborg/gdub A SCRIPT THAT CAN INVOKE A GRADLE BUILD ANYWHERE INSIDE THE PROJECT STRUCTURE. WILL ATTEMPT RESOLVING WRAPPER FIRST, THEN LOCAL GRADLE. FAILS IF NEITHER IS FOUND.
  • 14. CHANGE BUILD FILE NAMES CHANGE BULD FILE NAME FROM build.gradle TO ${project.name}.gradle USE GROOVY EXPRESSIONS TO FACTORIZE PROJECT INCLUSIONS IN settings.gradle
  • 15. SETTINGS.GRADLE (1/2) ['common',  'full',  'light'].each  {  name  -­‐>          File  subdir  =  new  File(rootDir,  name)          subdir.eachDir  {  dir  -­‐>                  File  buildFile  =  new  File(dir,  "${dir.name}.gradle")                  if  (buildFile.exists())  {                          include  "${name}/${dir.name}"                  }          }   }  
  • 16. SETTINGS.GRADLE (2/2) rootProject.name  =  'my-­‐project'   rootProject.children.each  {  project  -­‐>          int  slash  =  project.name.indexOf('/')          String  fileBaseName  =  project.name[(slash  +  1)..-­‐1]          String  projectDirName  =  project.name          project.name  =  fileBaseName          project.projectDir  =  new  File(settingsDir,  projectDirName)          project.buildFileName  =  "${fileBaseName}.gradle"          assert  project.projectDir.isDirectory()          assert  project.buildFile.isFile()   }  
  • 19. KEEP IT DRY EMBRACE THE POWER OF CONVENTIONS. BUILD FILE SHOULD DEFINE HOW THE PROJECT DEVIATES FROM THE PRE-ESTABLISHED CONVENTIONS. RELY ON SECONDARY SCRIPTS, SEGGREGATED BY RESPONSIBILITIES.
  • 20. TASK DEFINITIONS PUT THEM IN SEPARATE FILES. 1.  INSIDE SECONDARY SCRIPTS 1.  REGULAR TASK DEFINITIONS 2.  PLUGIN DEFINITIONS 2.  AS PART OF buildSrc SOURCES 3.  AS A PLUGIN PROJECT
  • 21. APPLYING PLUGINS USE THE PLUGINS BLOCK DSL IF IN A SINGLE PROJECT. PLUGINS BLOCK DOES NOT WORK IN SECONDARY SCRIPTS. USE THE OLD-SCHOOL SYNTAX IF IN A MULTI-PROJECT AND NOT ALL SUBPROJECTS REQUIRE THE SAME PLUGINS.
  • 22. 7 DON’T REINVENT THE WHEEL, APPLY PLUGINS INSTEAD
  • 24. USEFUL PLUGINS Versions id 'com.github.ben-manes.versions' version '0.14.0’ License id 'com.github.hierynomus.license' version '0.11.0’ Versioning id 'net.nemerosa.versioning' version '2.6.0'
  • 25. FILTERING VERSIONS apply  plugin:  'com.github.ben-­‐manes.versions'   dependencyUpdates.resolutionStrategy  =  {          componentSelection  {  rules  -­‐>                  rules.all  {  selection  -­‐>                          boolean  rejected  =  ['alpha',  'beta',  'rc’].any  {  qualifier  -­‐>                                  selection.candidate.version  ==~  /(?i).*[.-­‐]${qualifier}[.d-­‐]*/                          }                          if  (rejected)  {                                  selection.reject('Release  candidate')                          }                  }          }   }  
  • 26. 8 KEEP ALL VERSIONS IN ONE PLACE
  • 27. IN GRADLE.PROPERTIES (1) awaitilityVersion    =  2.0.0   bootstrapfxVersion  =  0.2.1   guiceVersion              =  4.1.0   hamcrestVersion        =  1.3   ikonliVersion            =  1.9.0   jacksonVersion          =  2.8.7   jdeferredVersion      =  1.2.5   jukitoVersion            =  1.5   junitVersion              =  4.12   lombokVersion            =  1.16.16   mbassadorVersion      =  1.3.0   miglayoutVersion      =  5.0   mockitoVersion          =  2.7.19   reactfxVersion          =  2.0-­‐M5   retrofitVersion        =  2.2.0   slf4jVersion              =  1.7.25   testfxVersion            =  4.0.6-­‐alpha   wiremockVersion        =  2.5.1  
  • 28. IN BUILD.GRADLE (2) dependencies  {          compile  "net.engio:mbassador:$mbassadorVersion"          compile  "org.reactfx:reactfx:$reactfxVersion"          compile  "org.slf4j:slf4j-­‐api:$slf4jVersion"          compile  "org.jdeferred:jdeferred-­‐core:$jdeferredVersion"          compile  "com.squareup.retrofit2:retrofit:$retrofitVersion"          compile  "com.squareup.retrofit2:converter-­‐jackson:$retrofitVersion"          compile  "com.fasterxml.jackson.core:jackson-­‐core:$jacksonVersion"          compile  "com.fasterxml.jackson.core:jackson-­‐annotations:$jacksonVersion"          compile  "com.fasterxml.jackson.core:jackson-­‐databind:$jacksonVersion"          /*  and  more  ...  */   }  
  • 30. FORCE VERSIONS AND CHECK configurations.all  {          resolutionStrategy.force  "jdepend:jdepend:$jdependVersion",                  "com.google.guava:guava:$guavaVersion",                  "junit:junit:$junitVersion",                  "cglib:cglib-­‐nodep:$cglibVersion",                  "org.asciidoctor:asciidoctorj:$asciidoctorjVersion",                  "org.codehau.groovy:groovy-­‐all:$groovyVersion",                  "org.slf4j:slf4j-­‐api:$slf4jVersion",                  "org.slf4j:slf4j-­‐simple:$slf4jVersion",                  "org.easytesting:fest-­‐util:$festUtilVersion"            resolutionStrategy.failOnVersionConflict()   }  
  • 32. MANIFEST ENTRIES ENRICH JAR MANIFESTS WITH ADDITIONAL ENTRIES SUCH AS 'Built-By': System.properties['user.name'], 'Created-By': "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})".toString(), 'Build-Date': buildDate, 'Build-Time': buildTime, 'Build-Revision': versioning.info.commit, 'Specification-Title': project.name, 'Specification-Version': project.version, 'Specification-Vendor': project.vendor, 'Implementation-Title': project.name, 'Implementation-Version': project.version, 'Implementation-Vendor': project.vendor
  • 34. INCREMENTAL BUILD ACTIVATED BY ADDING –t TO THE COMMAND LINE. EXECUTES A GIVEN COMMAND WHENEVER ITS RESOURCES (INPUTS) CHANGE. AVOID INVOKING THE CLEAN TASK AS MUCH AS YOU CAN.
  • 36. JACOCO OR BUST STEP 1: DEFINE A LIST OF PROJECTS TO INCLUDE ext  {          projectsWithCoverage  =  []          baseJaCocoDir  =  "${buildDir}/reports/jacoco/test/"          jacocoMergeExecFile  =  "${baseJaCocoDir  }jacocoTestReport.exec"          jacocoMergeReportHTMLFile  =  "${baseJaCocoDir  }/html/"          jacocoMergeReportXMLFile  =  "${baseJaCocoDir}/jacocoTestReport.xml"   }  
  • 37. JACOCO OR BUST STEP 2: ADD PROJECT TO COVERAGE LIST jacocoTestReport  {          group  =  'Reporting'          description  =  'Generate  Jacoco  coverage  reports  after  running  tests.'          additionalSourceDirs  =  project.files(sourceSets.main.allSource.srcDirs)          sourceDirectories  =  project.files(sourceSets.main.allSource.srcDirs)          classDirectories  =  project.files(sourceSets.main.output)          reports  {                  xml.enabled  =  true                  csv.enabled  =  false                  html.enabled  =  true          }   }   projectsWithCoverage  <<  project  
  • 38. JACOCO OR BUST STEP 3: DEFINE AGGREGATE TASKS IN ROOT PROJECT evaluationDependsOnChildren()  //  VERY  IMPORTANT!!     task  jacocoRootMerge(type:  org.gradle.testing.jacoco.tasks.JacocoMerge)  {          dependsOn  =  projectsWithCoverage.test  +   projectsWithCoverage.jacocoTestReport            executionData  =  projectsWithCoverage.jacocoTestReport.executionData          destinationFile  =  file(jacocoMergeExecFile)   }  
  • 39. JACOCO OR BUST STEP 3: DEFINE AGGREGATE TASKS IN ROOT PROJECT task  jacocoRootMergeReport(dependsOn:  jacocoRootMerge,  type:  JacocoReport)  {          executionData  projectsWithCoverage.jacocoTestReport.executionData          sourceDirectories  =  projectsWithCoverage.sourceSets.main.allSource.srcDirs          classDirectories  =  projectsWithCoverage.sourceSets.main.output            reports  {                  html.enabled  =  true                  xml.enabled  =  true                  html.destination  =  file(jacocoMergeReportHTMLFile)                  xml.destination  =  file(jacocoMergeReportXMLFile)          }   }  
  • 40. 13 MIND THE TARGET JAVA VERSION
  • 41. JDK8 VS JDK7 JOINT COMPILING GROOVY CODE MAY GIVE YOU HEADACHES IF THE SOURCE/TARGET COMPATIBILITY IS NOT SET RIGHT   tasks.withType(JavaCompile)  {  t  -­‐>          t.sourceCompatibility  =  project.sourceCompatibility          t.targetCompatibility  =  project.targetCompatibility   }     tasks.withType(GroovyCompile)  {  t  -­‐>          t.sourceCompatibility  =  project.sourceCompatibility          t.targetCompatibility  =  project.targetCompatibility   }  
  • 42. JDK8 JAVADOC TROUBLES JAVADOC IN JDK8 IS VERY PEDANTIC   if  (JavaVersion.current().isJava8Compatible())  {          tasks.withType(Javadoc)  {                  options.addStringOption('Xdoclint:none',  '-­‐quiet')          }   }  
  • 43. COMPILE WARNINGS ACTIVATE COMPILER WARNINGS AT WILL   tasks.withType(AbstractCompile)  {          if  (rootProject.hasProperty('lint')  &&  rootProject.lint.toBoolean())  {                  options.compilerArgs  =  [                          '-­‐Xlint:all',  '-­‐Xlint:deprecation',  '-­‐Xlint:unchecked'                  ]          }   }     $  ./gradlew  –Plint=true  compile