2. Dependency Resolver & Manager 3. Build Task Scheduler & Executor 4. Build By Convention Gradle is an opinionated framework on top of an unopinionated toolkit - Szczepan Faber
Build Groovy DSL 3. Support for Ivy & Maven Dependencies 4. Multi-Project Builds 5. Easy to add custom logic 6. 1st class integration w/ Ant builds 7. Extensive public API and plugin ecosystem 8. Task UP-TO-DATE checking
c k a g e ) 2.061s (r m - r t a r g e t & & m v n p a c k a g e ) ~35 lines < p r o j e c t x m l n s = " h t t p : / / m a v e n . a p a c h e . o r g / P O M / 4 . 0 . 0 " x m l n s : x s i = " h t t p : / / w w w . w 3 . o r g / 2 0 0 1 / X M L S x s i : s c h e m a L o c a t i o n = " h t t p : / / m a v e n . a p a c h e . o r g / P O M / 4 . 0 . 0 h t t p : / / m a v e n . a p a c h e . o r g / m a v e n - v 4 _ < m o d e l V e r s i o n > 4 . 0 . 0 < / m o d e l V e r s i o n > < g r o u p I d > d e . u u l m . v s < / g r o u p I d > < a r t i f a c t I d > n e t t y - e x a m p l e < / a r t i f a c t I d > < p a c k a g i n g > j a r < / p a c k a g i n g > < v e r s i o n > 1 . 0 - S N A P S H O T < / v e r s i o n > < n a m e > n e t t y - e x a m p l e < / n a m e > < u r l > h t t p : / / m a v e n . a p a c h e . o r g < / u r l > < d e p e n d e n c i e s > < d e p e n d e n c y > < g r o u p I d > j u n i t < / g r o u p I d > < a r t i f a c t I d > j u n i t < / a r t i f a c t I d > < v e r s i o n > 3 . 8 . 1 < / v e r s i o n > < s c o p e > t e s t < / s c o p e > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > o r g . j b o s s . n e t t y < / g r o u p I d > < a r t i f a c t I d > n e t t y < / a r t i f a c t I d > < v e r s i o n > 3 . 2 . 2 . F i n a l < / v e r s i o n > < / d e p e n d e n c y > < / d e p e n d e n c i e s > < b u i l d > < p l u g i n s >
l e b u i l d ) 2.161s (r m - r b u i l d / & & g r a d l e b u i l d ) ~13 lines a p p l y p l u g i n : ' j a v a ' a p p l y p l u g i n : ' m a v e n ' g r o u p = ' d e . u u l m . v s ' v e r s i o n = ' 1 . 0 - S N A P S H O T ' r e p o s i t o r i e s { j c e n t e r ( ) } d e p e n d e n c i e s { c o m p i l e ' o r g . j b o s s . n e t t y : n e t t y : 3 . 2 . 2 . F i n a l ' t e s t C o m p i l e ' j u n i t : j u n i t : 3 . 8 . 1 ' } t a r g e t C o m p a t i b i l i t y = ' 1 . 6 ' s o u r c e C o m p a t i b i l i t y = ' 1 . 6 '
o d o & & c d t o d o 2. Initialize project Create & edit b u i l d . g r a d l e g r a d l e i n i t - - t y p e g r o o v y - l i b r a r y Convert existing Maven pom.xml: g r a d l e i n i t
t a s k s : t a s k s - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A l l t a s k s r u n n a b l e f r o m r o o t p r o j e c t - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - B u i l d t a s k s - - - - - - - - - - - a s s e m b l e - A s s e m b l e s t h e o u t p u t s o f t h i s p r o j e c t . b u i l d - A s s e m b l e s a n d t e s t s t h i s p r o j e c t . b u i l d D e p e n d e n t s - A s s e m b l e s a n d t e s t s t h i s p r o j e c t a n d a l l p r o j e c t s t h a t d e p e n d o n i t . b u i l d N e e d e d - A s s e m b l e s a n d t e s t s t h i s p r o j e c t a n d a l l p r o j e c t s i t d e p e n d s o n . c l a s s e s - A s s e m b l e s c l a s s e s ' m a i n ' . c l e a n - D e l e t e s t h e b u i l d d i r e c t o r y . j a r - A s s e m b l e s a j a r a r c h i v e c o n t a i n i n g t h e m a i n c l a s s e s . t e s t C l a s s e s - A s s e m b l e s c l a s s e s ' t e s t ' . . . .
= m y v a l u e : JVM System Properties for Gradle JVM - P p r o j e c t p r o p = p r o j e c t v a l : Gradle Project properties Specify Build File (default: b u i l d . g r a d l e ) - b < p a t h t o b u i l d f i l e > Logging - i , - - i n f o : Log more Gradle information - d , - - d e b u g : Log more information than Info - s , - - s t a c k t r a c e : Log stacktrace on error - q , - - q u i e t : Log errors only (or printlns)
"actions" Each "action" is a o r g . g r a d l e . a p i . A c t i o n C l o s u r e is coerced into A c t i o n t a s k h e l l o W o r l d { / / d e f i n e s a n e w t a s k w i t h n a m e ' h e l l o W o r l d ' d o L a s t { / / a d d a c t i o n t o t h e e n d o f t h e a c t i o n l i s t p r i n t l n ' H e l l o W o r l d ! ' } }
j e c t instance t a s k is method from Gradle DSL (o r g . g r a d l e . a p i . P r o j e c t . t a s k ( S t r i n g n a m e , C l o s u r e c o n f i g u r e ) ) < < { . . } is shorthand for d o L a s t { . . } t a s k h e l l o W o r l d < < { p r i n t l n ' H e l l o W o r l d ! ' }
s O n creates an execution dependency All execution dependencies of a task must also be executed and completed before the task t a s k a < < { p r i n t l n ' a ' } t a s k b ( d e p e n d s O n : a ) < < { p r i n t l n ' b ' } $ g r a d l e b : a a : b b
y creates a finalization dependency The finalizer task is added if the finalized task is present in the task graph finalizer will execute after the finalized even when finalized fails finalizer will not execute if finalized did no work or was UP- TO-DATE t a s k c l e a n u p < < { p r i n t l n ' c l e a n u p ' } t a s k r u n < < p r i n t l n ' r u n ' r u n . f i n a l i z e d B y c l e a n u p / / ' r u n ' i s t h e " f i n a l i z e d " t a s k , ' c l e a n u p ' i s t h e " f i n a l i z e r " $ g r a d l e r u n : r u n r u n : c l e a n u p c l e a n u p
execution dependency m u s t R u n A f t e r Task A runs after Task B only if both are in the task graph Always respected s h o u l d R u n A f t e r Same as m u s t R u n A f t e r but less strict Ignored if Creates an ordering cycle When executing in parallel and all other dependencies are completed except the s h o u l d R u n A f t e r
< { p r i n t l n ' f i r s t ' } t a s k s e c o n d < < { p r i n t l n ' s e c o n d ' } s e c o n d . m u s t R u n A f t e r f i r s t $ g r a d l e s e c o n d : s e c o n d s e c o n d $ g r a d l e f i r s t : f i r s t f i r s t $ g r a d l e s e c o n d f i r s t : f i r s t f i r s t : s e c o n d s e c o n d
d y ( ) < < { p r i n t l n ' R e a d y ' } 3 . t i m e s { n u m - > t a s k " c o u n t $ { n u m + 1 } " < < { p r i n t l n n u m + 1 } } t a s k g o ( ) < < { p r i n t l n ' G o ! ' } c o u n t 3 . d e p e n d s O n r e a d y c o u n t 2 . d e p e n d s O n c o u n t 3 c o u n t 1 . d e p e n d s O n c o u n t 2 g o . d e p e n d s O n c o u n t 1 t a s k c o u n t d o w n ( d e p e n d s O n : g o )
name t a s k s . a d d R u l e ( ' P a t t e r n : c o u n t d o w n < F r o m > ' ) { S t r i n g t a s k N a m e - > i f ( t a s k N a m e . s t a r t s W i t h ( ' c o u n t d o w n ' ) ) { t a s k ( t a s k N a m e ) < < { ( ( t a s k N a m e - ' c o u n t d o w n ' ) . t o I n t e g e r ( ) . . 0 ) . e a c h { p r i n t l n i t } } } } $ g r a d l e c o u n t d o w n 5 : c o u n t d o w n 5 5 4 3 2 1 0 $ g r a d l e c o u n t d o w n 2 : c o u n t d o w n 2 2 1 0
of a task Compares current inputs & outputs against previous runs If the same, task is considered UP-TO-DATE and is skipped Inputs consist of files and map of properties (String: Object) Outputs consists of files Tasks with no outputs, are never considered UP-TO-DATE and always executed Tasks with outputs but no inputs is considered UP-TO-DATE if the output hasn't changed
g r a d l e . p r o p e r t i e s in the rootDir of the project From the command line w/ - P p r o p e r t y = v a l u e Gradle Properties are inherited by child project and merged with child's properties / / g r a d l e . p r o p e r t i e s c u r r e n t V e r s i o n = 1 . 0 / / b u i l d . g r a d l e a p p l y p l u g i n : ' j a v a ' v e r s i o n = c u r r e n t V e r s i o n
can be extends via Extra Properties Each object has a e x t property to access the space Initially define using e x t . < p r o p e r t y N a m e > , then treat like project property e x t . f o o = ' b a r ' t a s k e c h o F o o < < { p r i n t l n f o o } t a s k b a z { e x t . f o o = ' b a z ' d o L a s t { p r i n t l n f o o } } $ g r a d l e e c h o F o o e c h o F o o 2 : e c h o F o o b a r : e c h o F o o 2 b a z
e f t a s k N a m e s = [ ' f o o ' , ' b a r ' , ' b a z ' ] t a s k N a m e s . e a c h { n a m e - > t a s k s . c r e a t e ( n a m e ) < < { p r i n t l n n a m e } }
Expires after 3 hours g r a d l e - - d a e m o n e c h o " o r g . g r a d l e . d a e m o n = t r u e " > > ~ / . g r a d l e / g r a d l e . p r o p e r t i e s
e b u i l d : c o m p i l e J a v a U P - T O - D A T E : c o m p i l e G r o o v y : p r o c e s s R e s o u r c e s U P - T O - D A T E : c l a s s e s : j a r : a s s e m b l e : c o m p i l e T e s t J a v a U P - T O - D A T E : c o m p i l e T e s t G r o o v y : p r o c e s s T e s t R e s o u r c e s U P - T O - D A T E : t e s t C l a s s e s : t e s t : c h e c k : b u i l d B U I L D S U C C E S S F U L T o t a l t i m e : 6 . 2 1 3 s e c s
f i g u r a t i o n JVM projects have compile, runtime, testCompile, testRuntime Configurations can extend other repositories compile extends runtime d e p e n d e n c i e s { c o m p i l e ' o r g . c o d e h a u s . g r o o v y : g r o o v y - a l l : 2 . 3 . 3 ' r u n t i m e ' m y s q l : m y s q l - c o n n e c t o r - j a v a : 5 . 1 . 3 1 ' t e s t C o m p i l e ' o r g . s p o c k f r a m e w o r k : s p o c k - c o r e : 0 . 7 - g r o o v y - 2 . 0 ' t e s t R u n t i m e ' c o m . h 2 d a t a b a s e : h 2 : 1 . 4 . 1 8 0 ' }
mavenCentral, mavenLocal Can also look at custom maven, ivy, and file system paths r e p o s i t o r i e s { m a v e n L o c a l ( ) j c e n t e r ( ) m a v e n C e n t r a l ( ) m a v e n { u r l ' h t t p : / / m a v e n . m y h o s t . c o m / ' c r e d e n t i a l s { u s e r n a m e ' u s e r n a m e ' p a s s w o r d ' p a s s w o r d ' } } i v y { u r l ' h t t p : / / i v y . m y h o s t . c o m ' } f l a t D i r { d i r f i l e ( ' r e p o ' ) } }
o j e c t D i r > / + - - s r c / + - - m a i n / | + - - j a v a / | + - - g r o o v y / | + - - r e s o u r c e s / + - - t e s t / + - - j a v a / + - - g r o o v y / + - - r e s o u r c e s / But can be configured s o u r c e S e t s . m a i n . j a v a . s r c D i r s = [ ' s r c ' ] s o u r c e S e t s . t e s t . j a v a . s r c D i r s = [ ' t e s t ' ]
e S e t s JVM projects have 2 - m a i n & t e s t Each S o u r c e S e t starts w/ j a v a r e s o u r c e s a p p l y p l u g i n : ' j a v a ' s o u r c e S e t s { m a i n { j a v a { . . . } r e s o u r c e s { . . . } } t e s t { j a v a { . . . } r e s o u r c e s { . . . } } }
o u r c e S e t > / g r o o v y Scala adds < s o u r c e S e t > / s c a l a a p p l y p l u g i n : ' g r o o v y ' a p p l y p l u g i n : ' s c a l a ' s o u r c e S e t s { m a i n { g r o o v y { . . . } s c a l a { . . . } } t e s t { g r o o v y { . . . } s c a l a { . . . } } }
e t s (i.e "intTest") s o u r c e S e t s { i n t T e s t } Gradle automatically creates compile/runtime configurations for source sets / / N o n e e d t o d e c l a r e t h i s c o n f i g u r a t i o n s { i n t T e s t C o m p i l e i n t T e s t R u n t i m e }
dependencies in a filed Apply the file to your project / / d o c s . g r a d l e t a s k j a v a d o c J a r ( t y p e : J a r , d e p e n d s O n : j a v a d o c ) { c l a s s i f i e r = ' j a v a d o c ' f r o m ' b u i l d / d o c s / j a v a d o c ' } t a s k s o u r c e s J a r ( t y p e : J a r ) { c l a s s i f i e r = ' s o u r c e s ' f r o m s o u r c e S e t s . m a i n . a l l S o u r c e } b u i l d . d e p e n d s O n j a v a d o c J a r , s o u r c e s J a r / / b u i l d . g r a d l e a p p l y p l u g i n : ' g r o o v y ' a p p l y f r o m : f i l e ( ' d o c s . g r a d l e ' )
itself They are not project dependencies, need something else. Configure Gradle's executiong using b u i l d s c r i p t { } Similar to configure a normal project Find plugins at Gradle Plugin Portal - http://plugins.gradle.org b u i l d s c r i p t { r e p o s i t o r i e s { j c e n t e r ( ) } d e p e n d e n c i e s { c l a s s p a t h ' o r g . g i t h u b . j e n g e l m a n . g r a d l e . p l u g i n s : s h a d o w : 1 . 0 . 2 ' } } a p p l y p l u g i n : ' j a v a ' a p p l y p l u g i n : ' c o m . g i t h u b . j o h n r e n g e l m a n . s h a d o w '
isolated classloader Each classloader inherits from its parent classloader Apply a plugin in build.gradle and all subsequent script plugins can use classes from it Apply a plugin in a script plugin, then those classes are isolated to that script
r a d l e b u i l d s c r i p t { r e p o s i t o r i e s { j c e n t e r ( ) } d e p e n d e n c i e s { c l a s s p a t h ' c o m . g i t h u b . j e n g e l m a n . g r a d l e . p l u g i n s : s h a d o w : 1 . 0 . 2 ' } } i m p o r t c o m . g i t h u b . j e n g e l m a n . g r a d l e . p l u g i n s . s h a d o w . S h a d o w P l u g i n a p p l y p l u g i n : S h a d o w P l u g i n / / b u i l d . g r a d l e a p p l y p l u g i n : ' g r o o v y ' a p p l y f r o m : f i l e ( ' s h a d o w . g r a d l e ' ) i m p o r t c o m . g i t h u b . j e n g e l m a n . g r a d l e . p l u g i n s . s h a d o w . t a s k s . S h a d o w J a r t a s k c u s t o m S h a d o w ( t y p e : S h a d o w J a r ) / / N o C l a s s D e f F o u n d E x c e p t i o n o r M i s s i n g P r o p e r t y E x c e p t i o n
s . g r a d l e + < p r o j e c t D i r > + - - a p i / | + - - b u i l d . g r a d l e + - - c l i e n t / | + - - b u i l d . g r a d l e + - - s e r v e r / + - - b u i l d . g r a d l e / / s e t t i n g s . g r a d l e i n c l u d e " a p i " , " c l i e n t " , " s e r v e r " $ g r a d l e p r o j e c t s - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - R o o t p r o j e c t - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - R o o t p r o j e c t ' t o d o ' + - - - P r o j e c t ' : a p i ' + - - - P r o j e c t ' : c l i e n t ' \ - - - P r o j e c t ' : s e r v e r '
e r / b u i l d . g r a d l e d e p e n d e n c i e s { c o m p i l e p r o j e c t ( " : a p i " ) / / d e p e n d s o n a r t i f a c t s o f t h e ' d e f a u l t ' c o n f i g u r a t i o n }
b u i l d - - p a r a l l e l OR / / g r a d l e . p r o p e r t i e s o r ~ / . g r a d l e / g r a d l e . p r o p e r t i e s o r g . g r a d l e . p a r a l l e l = t r u e
Consultants Minneapolis, MN & Omaha, NE Chicago, IL & Denver, CO Average tenure > 5 years Founded in 1996 objectpartners.com @objectpartners objectpartners.com/blog