SlideShare a Scribd company logo
ANDRES ALMIRAY
@AALMIRAY
MAKING THE MOST OF
YOUR GRADLE BUILD
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
USEFUL PLUGINS
Versions
id 'com.github.ben-manes.versions' version '0.15.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	
  	
  =	
  3.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.8.9	
  
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'	
  
	
  	
  	
  	
  	
  	
  	
  	
  ]	
  
	
  	
  	
  	
  }	
  
}	
  
	
  
$	
  gw	
  –Plint=true	
  compile	
  
14
GET READY FOR JDK9
JDEPS TO THE RESCUE
VERIFIES PRODUCTION CLASSES AND DEPENDENCIES
	
  
plugins	
  {	
  	
  
	
  	
  	
  	
  id	
  'org.kordamp.jdeps'	
  version	
  '0.1.0'	
  	
  
}	
  
	
  
$	
  gw	
  jdeps	
  
15
PLUGINS! PLUGINS!
PLUGINS!
license
versions
stats
bintray
shadow
izpack
java2html
git
coveralls
asciidoctor
jbake
markdown
gretty
nexus
apt
ossindex
versioning
pitest
semantic-release
clirr
compass
flyway
jmh
macappbundle
osspackage
jnlp
spotless
dependency-
management
sshoogr
THANK YOU!
ANDRES ALMIRAY
@AALMIRAY

More Related Content

What's hot

Agile Android
Agile AndroidAgile Android
Agile Android
Godfrey Nolan
 
iOS Behavior-Driven Development
iOS Behavior-Driven DevelopmentiOS Behavior-Driven Development
iOS Behavior-Driven Development
Brian Gesiak
 
Java(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the UglyJava(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the Ugly
Brian Vermeer
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
Anton Arhipov
 
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
Schalk Cronjé
 
Android TDD
Android TDDAndroid TDD
Android TDD
Godfrey Nolan
 
Why Kotlin - Apalon Kotlin Sprint Part 1
Why Kotlin - Apalon Kotlin Sprint Part 1Why Kotlin - Apalon Kotlin Sprint Part 1
Why Kotlin - Apalon Kotlin Sprint Part 1
Kirill Rozov
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
David Rodenas
 
Agile Swift
Agile SwiftAgile Swift
Agile Swift
Godfrey Nolan
 
Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010
Tomek Kaczanowski
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM Development
Schalk Cronjé
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the Covers
Brian Gesiak
 
Spring & Hibernate
Spring & HibernateSpring & Hibernate
Spring & Hibernate
Jiayun Zhou
 
Java libraries you can't afford to miss
Java libraries you can't afford to missJava libraries you can't afford to miss
Java libraries you can't afford to miss
Andres Almiray
 
Java8 tgtbatu devoxxuk18
Java8 tgtbatu devoxxuk18Java8 tgtbatu devoxxuk18
Java8 tgtbatu devoxxuk18
Brian Vermeer
 
Apple Templates Considered Harmful
Apple Templates Considered HarmfulApple Templates Considered Harmful
Apple Templates Considered HarmfulBrian Gesiak
 
Springを用いた社内ライブラリ開発
Springを用いた社内ライブラリ開発Springを用いた社内ライブラリ開発
Springを用いた社内ライブラリ開発
Recruit Lifestyle Co., Ltd.
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Anton Arhipov
 
Arquillian Constellation
Arquillian ConstellationArquillian Constellation
Arquillian Constellation
Alex Soto
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in Grails
GR8Conf
 

What's hot (20)

Agile Android
Agile AndroidAgile Android
Agile Android
 
iOS Behavior-Driven Development
iOS Behavior-Driven DevelopmentiOS Behavior-Driven Development
iOS Behavior-Driven Development
 
Java(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the UglyJava(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the Ugly
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
 
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
 
Android TDD
Android TDDAndroid TDD
Android TDD
 
Why Kotlin - Apalon Kotlin Sprint Part 1
Why Kotlin - Apalon Kotlin Sprint Part 1Why Kotlin - Apalon Kotlin Sprint Part 1
Why Kotlin - Apalon Kotlin Sprint Part 1
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
Agile Swift
Agile SwiftAgile Swift
Agile Swift
 
Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM Development
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the Covers
 
Spring & Hibernate
Spring & HibernateSpring & Hibernate
Spring & Hibernate
 
Java libraries you can't afford to miss
Java libraries you can't afford to missJava libraries you can't afford to miss
Java libraries you can't afford to miss
 
Java8 tgtbatu devoxxuk18
Java8 tgtbatu devoxxuk18Java8 tgtbatu devoxxuk18
Java8 tgtbatu devoxxuk18
 
Apple Templates Considered Harmful
Apple Templates Considered HarmfulApple Templates Considered Harmful
Apple Templates Considered Harmful
 
Springを用いた社内ライブラリ開発
Springを用いた社内ライブラリ開発Springを用いた社内ライブラリ開発
Springを用いた社内ライブラリ開発
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011
 
Arquillian Constellation
Arquillian ConstellationArquillian Constellation
Arquillian Constellation
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in Grails
 

Similar to Making the most of your gradle build - Gr8Conf 2017

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
Corneil du Plessis
 
GradleFX
GradleFXGradleFX
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
Schalk Cronjé
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 version
Schalk Cronjé
 
Making the most of your gradle build - BaselOne 2017
Making the most of your gradle build - BaselOne 2017Making the most of your gradle build - BaselOne 2017
Making the most of your gradle build - BaselOne 2017
Andres Almiray
 
Making the most of your gradle build - vJUG24 2017
Making the most of your gradle build - vJUG24 2017Making the most of your gradle build - vJUG24 2017
Making the most of your gradle build - vJUG24 2017
Andres Almiray
 
Gradle in 45min
Gradle in 45minGradle in 45min
Gradle in 45min
Schalk Cronjé
 
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
Skills Matter
 
Idiomatic gradle plugin writing
Idiomatic gradle plugin writingIdiomatic gradle plugin writing
Idiomatic gradle plugin writing
Schalk Cronjé
 
Dropwizard and Friends
Dropwizard and FriendsDropwizard and Friends
Dropwizard and Friends
Yun Zhi Lin
 
Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016
Alvaro Sanchez-Mariscal
 
From Zero to Application Delivery with NixOS
From Zero to Application Delivery with NixOSFrom Zero to Application Delivery with NixOS
From Zero to Application Delivery with NixOS
Susan Potter
 
Basic Gradle Plugin Writing
Basic Gradle Plugin WritingBasic Gradle Plugin Writing
Basic Gradle Plugin Writing
Schalk Cronjé
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
Thierry Wasylczenko
 
Enter the gradle
Enter the gradleEnter the gradle
Enter the gradle
Parameswari Ettiappan
 
Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Tino Isnich
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
Schalk Cronjé
 
Get Grulping with JavaScript Task Runners (Matt Gifford)
Get Grulping with JavaScript Task Runners (Matt Gifford)Get Grulping with JavaScript Task Runners (Matt Gifford)
Get Grulping with JavaScript Task Runners (Matt Gifford)
Future Insights
 

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

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
 
GradleFX
GradleFXGradleFX
GradleFX
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 version
 
Making the most of your gradle build - BaselOne 2017
Making the most of your gradle build - BaselOne 2017Making the most of your gradle build - BaselOne 2017
Making the most of your gradle build - BaselOne 2017
 
Making the most of your gradle build - vJUG24 2017
Making the most of your gradle build - vJUG24 2017Making the most of your gradle build - vJUG24 2017
Making the most of your gradle build - vJUG24 2017
 
Gradle in 45min
Gradle in 45minGradle in 45min
Gradle in 45min
 
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
 
Idiomatic gradle plugin writing
Idiomatic gradle plugin writingIdiomatic gradle plugin writing
Idiomatic gradle plugin writing
 
Dropwizard and Friends
Dropwizard and FriendsDropwizard and Friends
Dropwizard and Friends
 
Play framework
Play frameworkPlay framework
Play framework
 
Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016Mastering Grails 3 Plugins - G3 Summit 2016
Mastering Grails 3 Plugins - G3 Summit 2016
 
From Zero to Application Delivery with NixOS
From Zero to Application Delivery with NixOSFrom Zero to Application Delivery with NixOS
From Zero to Application Delivery with NixOS
 
Basic Gradle Plugin Writing
Basic Gradle Plugin WritingBasic Gradle Plugin Writing
Basic Gradle Plugin Writing
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Enter the gradle
Enter the gradleEnter the gradle
Enter the gradle
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
Get Grulping with JavaScript Task Runners (Matt Gifford)
Get Grulping with JavaScript Task Runners (Matt Gifford)Get Grulping with JavaScript Task Runners (Matt Gifford)
Get Grulping with JavaScript Task Runners (Matt Gifford)
 

More from Andres Almiray

Creando, creciendo, y manteniendo una comunidad de codigo abierto
Creando, creciendo, y manteniendo una comunidad de codigo abiertoCreando, creciendo, y manteniendo una comunidad de codigo abierto
Creando, creciendo, y manteniendo una comunidad de codigo abierto
Andres Almiray
 
Liberando a produccion con confianza
Liberando a produccion con confianzaLiberando a produccion con confianza
Liberando a produccion con confianza
Andres Almiray
 
Liberando a produccion con confidencia
Liberando a produccion con confidenciaLiberando a produccion con confidencia
Liberando a produccion con confidencia
Andres Almiray
 
OracleDB Ecosystem for Java Developers
OracleDB Ecosystem for Java DevelopersOracleDB Ecosystem for Java Developers
OracleDB Ecosystem for Java Developers
Andres Almiray
 
Softcon.ph - Maven Puzzlers
Softcon.ph - Maven PuzzlersSoftcon.ph - Maven Puzzlers
Softcon.ph - Maven Puzzlers
Andres Almiray
 
Maven Puzzlers
Maven PuzzlersMaven Puzzlers
Maven Puzzlers
Andres Almiray
 
Oracle Database Ecosystem for Java Developers
Oracle Database Ecosystem for Java DevelopersOracle Database Ecosystem for Java Developers
Oracle Database Ecosystem for Java Developers
Andres Almiray
 
JReleaser - Releasing at the speed of light
JReleaser - Releasing at the speed of lightJReleaser - Releasing at the speed of light
JReleaser - Releasing at the speed of light
Andres Almiray
 
Building modular applications with the Java Platform Module System and Layrry
Building modular applications with the Java Platform Module System and LayrryBuilding modular applications with the Java Platform Module System and Layrry
Building modular applications with the Java Platform Module System and Layrry
Andres Almiray
 
Going Reactive with g rpc
Going Reactive with g rpcGoing Reactive with g rpc
Going Reactive with g rpc
Andres Almiray
 
Building modular applications with JPMS and Layrry
Building modular applications with JPMS and LayrryBuilding modular applications with JPMS and Layrry
Building modular applications with JPMS and Layrry
Andres Almiray
 
Taking Micronaut out for a spin
Taking Micronaut out for a spinTaking Micronaut out for a spin
Taking Micronaut out for a spin
Andres Almiray
 
Apache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouApache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and You
Andres Almiray
 
What I wish I knew about Maven years ago
What I wish I knew about Maven years agoWhat I wish I knew about Maven years ago
What I wish I knew about Maven years ago
Andres Almiray
 
What I wish I knew about maven years ago
What I wish I knew about maven years agoWhat I wish I knew about maven years ago
What I wish I knew about maven years ago
Andres Almiray
 
The impact of sci fi in tech
The impact of sci fi in techThe impact of sci fi in tech
The impact of sci fi in tech
Andres Almiray
 
Gradle Ex Machina - Devoxx 2019
Gradle Ex Machina - Devoxx 2019Gradle Ex Machina - Devoxx 2019
Gradle Ex Machina - Devoxx 2019
Andres Almiray
 
Creating Better Builds with Gradle
Creating Better Builds with GradleCreating Better Builds with Gradle
Creating Better Builds with Gradle
Andres Almiray
 
Interacting with the Oracle Cloud Java SDK with Gradle
Interacting with the Oracle Cloud Java SDK with GradleInteracting with the Oracle Cloud Java SDK with Gradle
Interacting with the Oracle Cloud Java SDK with Gradle
Andres Almiray
 
Gradle ex-machina
Gradle ex-machinaGradle ex-machina
Gradle ex-machina
Andres Almiray
 

More from Andres Almiray (20)

Creando, creciendo, y manteniendo una comunidad de codigo abierto
Creando, creciendo, y manteniendo una comunidad de codigo abiertoCreando, creciendo, y manteniendo una comunidad de codigo abierto
Creando, creciendo, y manteniendo una comunidad de codigo abierto
 
Liberando a produccion con confianza
Liberando a produccion con confianzaLiberando a produccion con confianza
Liberando a produccion con confianza
 
Liberando a produccion con confidencia
Liberando a produccion con confidenciaLiberando a produccion con confidencia
Liberando a produccion con confidencia
 
OracleDB Ecosystem for Java Developers
OracleDB Ecosystem for Java DevelopersOracleDB Ecosystem for Java Developers
OracleDB Ecosystem for Java Developers
 
Softcon.ph - Maven Puzzlers
Softcon.ph - Maven PuzzlersSoftcon.ph - Maven Puzzlers
Softcon.ph - Maven Puzzlers
 
Maven Puzzlers
Maven PuzzlersMaven Puzzlers
Maven Puzzlers
 
Oracle Database Ecosystem for Java Developers
Oracle Database Ecosystem for Java DevelopersOracle Database Ecosystem for Java Developers
Oracle Database Ecosystem for Java Developers
 
JReleaser - Releasing at the speed of light
JReleaser - Releasing at the speed of lightJReleaser - Releasing at the speed of light
JReleaser - Releasing at the speed of light
 
Building modular applications with the Java Platform Module System and Layrry
Building modular applications with the Java Platform Module System and LayrryBuilding modular applications with the Java Platform Module System and Layrry
Building modular applications with the Java Platform Module System and Layrry
 
Going Reactive with g rpc
Going Reactive with g rpcGoing Reactive with g rpc
Going Reactive with g rpc
 
Building modular applications with JPMS and Layrry
Building modular applications with JPMS and LayrryBuilding modular applications with JPMS and Layrry
Building modular applications with JPMS and Layrry
 
Taking Micronaut out for a spin
Taking Micronaut out for a spinTaking Micronaut out for a spin
Taking Micronaut out for a spin
 
Apache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouApache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and You
 
What I wish I knew about Maven years ago
What I wish I knew about Maven years agoWhat I wish I knew about Maven years ago
What I wish I knew about Maven years ago
 
What I wish I knew about maven years ago
What I wish I knew about maven years agoWhat I wish I knew about maven years ago
What I wish I knew about maven years ago
 
The impact of sci fi in tech
The impact of sci fi in techThe impact of sci fi in tech
The impact of sci fi in tech
 
Gradle Ex Machina - Devoxx 2019
Gradle Ex Machina - Devoxx 2019Gradle Ex Machina - Devoxx 2019
Gradle Ex Machina - Devoxx 2019
 
Creating Better Builds with Gradle
Creating Better Builds with GradleCreating Better Builds with Gradle
Creating Better Builds with Gradle
 
Interacting with the Oracle Cloud Java SDK with Gradle
Interacting with the Oracle Cloud Java SDK with GradleInteracting with the Oracle Cloud Java SDK with Gradle
Interacting with the Oracle Cloud Java SDK with Gradle
 
Gradle ex-machina
Gradle ex-machinaGradle ex-machina
Gradle ex-machina
 

Recently uploaded

Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 

Recently uploaded (20)

Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 

Making the most of your gradle build - Gr8Conf 2017

  • 1. ANDRES ALMIRAY @AALMIRAY MAKING THE MOST OF YOUR GRADLE BUILD
  • 2.
  • 3.
  • 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
  • 23.
  • 24. USEFUL PLUGINS Versions id 'com.github.ben-manes.versions' version '0.15.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    =  3.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.8.9   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'                  ]          }   }     $  gw  –Plint=true  compile  
  • 45. JDEPS TO THE RESCUE VERIFIES PRODUCTION CLASSES AND DEPENDENCIES   plugins  {            id  'org.kordamp.jdeps'  version  '0.1.0'     }     $  gw  jdeps