Top Banner
© ASERT 2008-2010 Make Your Builds More Groovy Dr Paul King [email protected] @paulk_asert ASERT, Australia ESDC 2010 - 1
68

Make Your Builds More Groovy

Jan 26, 2015

Download

Technology

Paul King

Groovy with Ant, Maven and Gradle
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Make Your Builds More Groovy

© A

SE

RT

20

08

-20

10

Make Your Builds More Groovy

Dr Paul King

[email protected]

@paulk_asert

ASERT, Australia

ESDC 2010 - 1

Page 2: Make Your Builds More Groovy

Topics

Build Pain Points

• Build Tool Landscape

• Groovy Intro

• Ant & friends

• Maven & friends

• Gradle

• Other Tools

• More Info

ESDC 2010 - 2

© A

SE

RT

20

08

-20

10

Page 3: Make Your Builds More Groovy

Build Pain Points...

• Has anyone seen?

– Large monolithic balls of mud

– Complex usage, assumptions, conventions

– Impossible to bend in desired ways

– Never been (can't be) refactored/tested

– Many manual steps

– Environment fragile

• different machines, CI vs IDE, dev vs prod vs test

ESDC 2010 - 3

© A

SE

RT

20

08

-20

10

Page 4: Make Your Builds More Groovy

...Build Pain Points...

• Require powerful features– Dependency management

– Version management

– Polyglot compilation

– Artifact production and manipulation (jar, war, ...)

– Templating (generation of boilerplate text files)

– Multifacted testing

– Reporting

– Quality control (Metrics, code quality, static analysis)

– Property management

– Infinitely(?) extensible

ESDC 2010 - 4

© A

SE

RT

20

08

-20

10

Page 5: Make Your Builds More Groovy

...Build Pain Points

• Useful characteristics– Tool friendly

– Cross platform

– IDE support, CI support

– Refactorable

– Testable

– Minimal noise (DSL like)

– Easy to extend

– Conventions

– Good documentation

– Polyglot friendly

ESDC 2010 - 5

© A

SE

RT

20

08

-20

10

Page 6: Make Your Builds More Groovy

Topics

• Build Pain Points

Build Tool Landscape

• Groovy Intro

• Ant & friends

• Maven & friends

• Gradle

• Other Tools

• More Info

ESDC 2010 - 6

© A

SE

RT

20

08

-20

10

Page 7: Make Your Builds More Groovy

Build Tools

• Non-exhaustive list– Ant, Maven, EasyAnt

– Gant, GMaven, Gradle, Graven (uptake?),

Groovy Frontend for Ant (emerge from sandbox?)

– Rake, Raven, Buildr

– Make, SCons, Waf

– MSBuild, Nant

• Used by– Developers: NetBeans, Eclipse, Intellij, Command-line

– CI: Hudson (Groovy support and console), Team City,

CruiseControl, AnthillPro (Groovy support), Bamboo

– Deployment Management: Tableaux (Groovy support)

– Ad-hoc: batch processing, production applications

ESDC 2010 - 7

© A

SE

RT

20

08

-20

10

Page 8: Make Your Builds More Groovy

Pros/Cons of Traditional Tools• Ant

– Flexible (supports any

convention)

– Easy to extend

– Wealth of useful tasks

– Well documented

– Partially declarative but

some scope for

procedural instructions

• XML != prog. language

– Lifecycle is hand-crafted

in your build file

– Can use Ivy or Maven Ant

tasks for dependency

management

• Maven

– Opinionated about

conventions

• Mostly a good thing

– Mostly declarative

• XML != concise DSL

– Numerous plugins

– Some easy extension

points but some more

difficult options

• Some things beyond

some teams

– Structured lifecycle

ESDC 2010 - 8

© A

SE

RT

20

08

-20

10

Page 9: Make Your Builds More Groovy

Enhancing Traditional Tools• Ant + Groovy

– Easy to write the

procedural pieces

– Easier to refactor

– Easier to test

– Ease of creating a build

DSL

– More concise

– Better interaction with

Java

– No impedence

mismatch with

developers

• Maven + Groovy

– Easier to extend

– More concise syntax

– Some scope for

refactoring

• Gradle

– Take the best of both

worlds and combine

them

ESDC 2010 - 9

© A

SE

RT

20

08

-20

10

Page 10: Make Your Builds More Groovy

A Preview Example...

ESDC 2010 - 10

© A

SE

RT

20

08

-20

10

Page 11: Make Your Builds More Groovy

...A Preview Example...

ESDC 2010 - 11

© A

SE

RT

20

08

-20

10

<project name="StringUtilsBuild" default="package"xmlns:ivy="antlib:org.apache.ivy.ant" xmlns="antlib:org.apache.tools.ant">

<target name="clean"><delete dir="target"/><delete dir="lib"/>

</target>

<target name="compile" depends="-init-ivy"><mkdir dir="target/classes"/><javac srcdir="src/main"

destdir="target/classes"/></target>

<target name="compileTest" depends="compile"><mkdir dir="target/test-classes"/><javac srcdir="src/test"

destdir="target/test-classes"><classpath>

<pathelement location="target/classes"/><fileset dir="lib" includes="*.jar"/>

</classpath></javac>

</target>

<target name="test" depends="compileTest"><mkdir dir="target/test-reports"/><junit printsummary="yes" fork="yes" haltonfailure="yes">

<classpath><pathelement location="target/classes"/><pathelement location="target/test-classes"/><fileset dir="lib" includes="*.jar"/>

</classpath><formatter type="plain"/><formatter type="xml"/><batchtest fork="yes" todir="target/test-reports">

<fileset dir="target/test-classes"/></batchtest>

</junit></target>

<target name="package" depends="test"><jar destfile="target/stringutils-1.0-SNAPSHOT.jar"

basedir="target/classes"/></target>

<target name="-init-ivy" depends="-download-ivy"><taskdef resource="org/apache/ivy/ant/antlib.xml"

uri="antlib:org.apache.ivy.ant" classpath="lib/ivy.jar"/><ivy:settings file="ivysettings.xml"/><ivy:retrieve/>

</target>

<target name="-download-ivy"><property name="ivy.version" value="2.1.0-rc2"/><mkdir dir="lib"/><get

src="http://repo2.maven.org/maven2/org/apache/ivy/ivy/${ivy.version}/ivy-${ivy.version}.jar"

dest="lib/ivy.jar" usetimestamp="true"/></target>

</project>

<?xml version="1.0" encoding="ISO-8859-1"?><ivy-module version="1.0">

<info organisation="org" module="groovycookbook" /><dependencies>

<dependency name="junit" rev="4.7" /></dependencies>

</ivy-module>

<ivysettings><settings defaultResolver="chained"/><resolvers><chain name="chained" returnFirst="true">

<ibiblio name="ibiblio" /><url name="ibiblio-mirror"><artifact

pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/[module]/[branch]/[revision]/[branch]-[revision].[ext]" />

</url></chain>

</resolvers></ivysettings>

StringUtils: Vanilla Ant + Ivy

Page 12: Make Your Builds More Groovy

...A Preview Example...

ESDC 2010 - 12

© A

SE

RT

20

08

-20

10

import static groovy.xml.NamespaceBuilder.newInstance as namespace

ant = new AntBuilder()clean()doPackage()

def doPackage() {test()ant.jar destfile: 'target/stringutils-1.0-SNAPSHOT.jar',

basedir: 'target/classes'}

private dependencies() {def ivy_version = '2.1.0-rc2'def repo = 'http://repo2.maven.org/maven2'ant.mkdir dir: 'lib'ant.get dest: 'lib/ivy.jar',

usetimestamp: 'true',src: "$repo/org/apache/ivy/ivy/$ivy_version/ivy-${ivy_version}.jar"

ant.taskdef classpath: 'lib/ivy.jar',uri: 'antlib:org.apache.ivy.ant',resource: 'org/apache/ivy/ant/antlib.xml'

def ivy = namespace(ant, 'antlib:org.apache.ivy.ant')ivy.settings file: 'ivysettings.xml'ivy.retrieve()

}

def clean() {ant.delete dir: 'target'ant.delete dir: 'lib'

}

def compile() {dependencies()ant.mkdir dir: 'target/classes'ant.javac destdir: 'target/classes', srcdir: 'src/main',

includeantruntime: false}

def compileTest() {compile()ant.mkdir dir: 'target/test-classes'ant.javac(destdir: 'target/test-classes', srcdir: 'src/test',

includeantruntime: false) {classpath {

pathelement location: 'target/classes'fileset dir: 'lib', includes: '*.jar'

}}

}...

<?xml version="1.0" encoding="ISO-8859-1"?><ivy-module version="1.0">

<info organisation="org" module="groovycookbook" /><dependencies>

<dependency name="junit" rev="4.7" /></dependencies>

</ivy-module>

<ivysettings><settings defaultResolver="chained"/><resolvers><chain name="chained" returnFirst="true">

<ibiblio name="ibiblio" /><url name="ibiblio-mirror"><artifact

pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/[module]/[branch]/[revision]/[branch]-[revision].[ext]" />

</url></chain>

</resolvers></ivysettings>

StringUtils: Groovy's AntBuilder...

def test() {compileTest()ant.mkdir dir: 'target/test-reports'ant.junit(printsummary: 'yes', haltonfailure: 'yes', fork: 'yes') {

classpath {pathelement location: 'target/classes'pathelement location: 'target/test-classes'fileset dir: 'lib', includes: '*.jar'

}formatter type: 'plain'formatter type: 'xml'batchtest(todir: 'target/test-reports', fork: 'yes') {

fileset dir: 'target/test-classes'}

}}

Page 13: Make Your Builds More Groovy

...A Preview Example...

ESDC 2010 - 13

© A

SE

RT

20

08

-20

10

import static groovy.xml.NamespaceBuilder.newInstance as namespace

target('package': '') {depends 'test'jar destfile: 'target/stringutils-1.0-SNAPSHOT.jar',

basedir: 'target/classes'}

target('-download-ivy': '') {def ivy_version = '2.1.0-rc2'def repo = 'http://repo2.maven.org/maven2'mkdir dir: 'lib'get dest: 'lib/ivy.jar',

usetimestamp: 'true',src: "$repo/org/apache/ivy/ivy/$ivy_version/ivy-${ivy_version}.jar"

}

target(clean: '') {delete dir: 'target'delete dir: 'lib'

}

target(compile: '') {depends '-init-ivy'mkdir dir: 'target/classes'javac destdir: 'target/classes', srcdir: 'src/main'

}

target('-init-ivy': '') {depends '-download-ivy'taskdef classpath: 'lib/ivy.jar',

uri: 'antlib:org.apache.ivy.ant',resource: 'org/apache/ivy/ant/antlib.xml'

def ivy = namespace(ant, 'antlib:org.apache.ivy.ant')ivy.settings file: 'ivysettings.xml'ivy.retrieve()

}

target(compileTest: '') {depends 'compile'mkdir dir: 'target/test-classes'javac(destdir: 'target/test-classes', srcdir: 'src/test') {

classpath {pathelement location: 'target/classes'fileset dir: 'lib', includes: '*.jar'

}}

}...

<?xml version="1.0" encoding="ISO-8859-1"?><ivy-module version="1.0">

<info organisation="org" module="groovycookbook" /><dependencies>

<dependency name="junit" rev="4.7" /></dependencies>

</ivy-module>

<ivysettings><settings defaultResolver="chained"/><resolvers><chain name="chained" returnFirst="true">

<ibiblio name="ibiblio" /><url name="ibiblio-mirror"><artifact

pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/[module]/[branch]/[revision]/[branch]-[revision].[ext]" />

</url></chain>

</resolvers></ivysettings>

StringUtils: Gant...

target(test: '') {depends 'compileTest'mkdir dir: 'target/test-reports'junit(printsummary: 'yes', haltonfailure: 'yes', fork: 'yes') {

classpath {pathelement location: 'target/classes'pathelement location: 'target/test-classes'fileset dir: 'lib', includes: '*.jar'

}formatter type: 'plain'formatter type: 'xml'batchtest(todir: 'target/test-reports', fork: 'yes') {

fileset dir: 'target/test-classes'}

}}

setDefaultTarget 'package'

Page 14: Make Your Builds More Groovy

...A Preview Example...

ESDC 2010 - 14

© A

SE

RT

20

08

-20

10

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.groovycookbook.builds</groupId><artifactId>stringutils</artifactId><packaging>jar</packaging><version>1.0-SNAPSHOT</version><name>stringutils</name><url>http://maven.apache.org</url><dependencies>

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.7</version><scope>test</scope>

</dependency></dependencies><build>

<plugins><!-- this is a java 1.5 project --><plugin>

<groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration>

<source>1.5</source><target>1.5</target>

</configuration></plugin>

</plugins></build>

</project>

StringUtils: Maven

Page 15: Make Your Builds More Groovy

...A Preview Example...

ESDC 2010 - 15

© A

SE

RT

20

08

-20

10

project {modelVersion '4.0.0'groupId 'org.groovycookbook.builds'artifactId 'stringutils'packaging 'jar'version '1.0-SNAPSHOT'name 'stringutils'url 'http://maven.apache.org'dependencies {dependency 'junit:junit:4.7:test'

}build {plugins {/* this is a java 1.5 project */plugin {groupId 'org.apache.maven.plugins'artifactId 'maven-compiler-plugin'configuration {

source '1.5'target '1.5'

}}

}}

}

StringUtils: Maven 3 Groovy Dialect

Page 16: Make Your Builds More Groovy

...A Preview Example

ESDC 2010 - 16

© A

SE

RT

20

08

-20

10

usePlugin 'java'

sourceCompatibility = 1.5version = '1.0-SNAPSHOT'

repositories {mavenCentral()

}

dependencies {testCompile 'junit:junit:4.7'

}

StringUtils: Gradle

Page 17: Make Your Builds More Groovy

Topics

• Build Pain Points

• Build Tool Landscape

Groovy Intro

• Ant & friends

• Maven & friends

• Gradle

• Other Tools

• More Info

ESDC 2010 - 17

© A

SE

RT

20

08

-20

10

Page 18: Make Your Builds More Groovy

ESDC 2010 - 18

© A

SE

RT

20

08

-20

10

What is Groovy?

• “Groovy is like a super version

of Java. It can leverage Java's

enterprise capabilities but also

has cool productivity features like closures,

DSL support, builders and dynamic typing.”

Groovy = Java – boiler plate code+ optional dynamic typing+ closures+ domain specific languages+ builders+ metaprogramming+ GDK library

Page 19: Make Your Builds More Groovy

ESDC 2010 - 19

© A

SE

RT

20

08

-20

10

Groovy Goodies Overview• Fully object oriented

• Closures: reusable

and assignable

pieces of code

• Operators can be

overloaded

• Multimethods

• Literal declaration for

lists (arrays), maps,

ranges and regular

expressions

• GPath: efficient

object navigation

• GroovyBeans

• grep and switch

• Templates, builder,

swing, Ant, markup,

XML, SQL, XML-RPC,

Scriptom, Grails,

tests, Mocks

Page 20: Make Your Builds More Groovy

Growing Acceptance …

A slow and steady start but now gaining in

momentum, maturity and mindshare

Now free

Page 21: Make Your Builds More Groovy

… Growing Acceptance …

© A

SE

RT

20

08

-20

10

ESDC 2010 - 21

Page 22: Make Your Builds More Groovy

… Growing Acceptance …

© A

SE

RT

20

08

-20

10

ESDC 2010 - 22

Groovy and Grails downloads:70-90K per month and growing

Page 23: Make Your Builds More Groovy

… Growing Acceptance …

© A

SE

RT

20

08

-20

10

ESDC 2010 - 23

Source: http://www.grailspodcast.com/

Source: http://www.micropoll.com/akira/mpresult/501697-116746

Page 24: Make Your Builds More Groovy

… Growing Acceptance …

© A

SE

RT

20

08

-20

10

ESDC 2010 - 24http://www.java.net

http://www.jroller.com/scolebourne/entry/devoxx_2008_whiteboard_votes

Page 25: Make Your Builds More Groovy

… Growing Acceptance

© A

SE

RT

20

06

-20

10

ESDC 2010 - 25

http://pollpigeon.com/jsf-grails-wicket/r/25665/

Page 26: Make Your Builds More Groovy

… Growing Acceptance …

© A

SE

RT

20

08

-20

10

ESDC 2010 - 26http://www.leonardoborges.com/writings

What alternative JVM language are you using or intending to use

Page 27: Make Your Builds More Groovy

… Growing Acceptance …

© A

SE

RT

20

08

-20

10

ESDC 2010 - 27

http://it-republik.de/jaxenter/quickvote/results/1/poll/44 (translated using http://babelfish.yahoo.com)

Page 28: Make Your Builds More Groovy

… Growing Acceptance

ESDC 2010 - 28

© A

SE

RT

20

08

-20

10

Page 29: Make Your Builds More Groovy

ESDC 2010 - 29

© A

SE

RT

20

08

-20

10

The Landscape of JVM Languages

Java bytecode calls

for static types

Dynamic features call

for dynamic types

mostly

dynamic

typing

The terms “Java Virtual Machine” and “JVM” mean a Virtual Machine for the Java™ platform.

Page 30: Make Your Builds More Groovy

ESDC 2010 - 30

© A

SE

RT

20

08

-20

10

Groovy StarterSystem.out.println("Hello, World!"); // optional semicolon,println 'Hello, World!' // System.out, brackets,

// main() method, class defn

def name = 'Guillaume' // dynamic typingprintln "$name, I'll get the car." // GString

String longer = """${name}, the caris in the next row.""" // multi-line string

// with static typing

assert 0.5 == 1/2 // BigDecimal equals()

def printSize(obj) { // optional duck typingprint obj?.size() // safe dereferencing

}

def pets = ['ant', 'bee', 'cat'] // native list syntaxpets.each { pet -> // closure support

assert pet < 'dog' // overloading '<' on String} // or: for (pet in pets)...

Page 31: Make Your Builds More Groovy

A Better Java...

ESDC 2010 - 31

© A

SE

RT

20

08

-20

10

import java.util.List;import java.util.ArrayList;

class Erase {private List removeLongerThan(List strings, int length) {

List result = new ArrayList();for (int i = 0; i < strings.size(); i++) {

String s = (String) strings.get(i);if (s.length() <= length) {

result.add(s);}

}return result;

}public static void main(String[] args) {

List names = new ArrayList();names.add("Ted"); names.add("Fred");names.add("Jed"); names.add("Ned");System.out.println(names);Erase e = new Erase();List shortNames = e.removeLongerThan(names, 3);System.out.println(shortNames.size());for (int i = 0; i < shortNames.size(); i++) {

String s = (String) shortNames.get(i);System.out.println(s);

}}

}

This codeis validJava andvalid Groovy

Based on anexample byJim Weirich& Ted Leung

Page 32: Make Your Builds More Groovy

...A Better Java...

ESDC 2010 - 32

© A

SE

RT

20

08

-20

10

import java.util.List;import java.util.ArrayList;

class Erase {private List removeLongerThan(List strings, int length) {

List result = new ArrayList();for (int i = 0; i < strings.size(); i++) {

String s = (String) strings.get(i);if (s.length() <= length) {

result.add(s);}

}return result;

}public static void main(String[] args) {

List names = new ArrayList();names.add("Ted"); names.add("Fred");names.add("Jed"); names.add("Ned");System.out.println(names);Erase e = new Erase();List shortNames = e.removeLongerThan(names, 3);System.out.println(shortNames.size());for (int i = 0; i < shortNames.size(); i++) {

String s = (String) shortNames.get(i);System.out.println(s);

}}

}

Do thesemicolonsadd anything?And shouldn‟twe us moremodern listnotation?Why notimport commonlibraries?

Page 33: Make Your Builds More Groovy

...A Better Java...

ESDC 2010 - 33

© A

SE

RT

20

08

-20

10

class Erase {private List removeLongerThan(List strings, int length) {

List result = new ArrayList()for (String s in strings) {

if (s.length() <= length) {result.add(s)

}}return result

}

public static void main(String[] args) {List names = new ArrayList()names.add("Ted"); names.add("Fred")names.add("Jed"); names.add("Ned")System.out.println(names)Erase e = new Erase()List shortNames = e.removeLongerThan(names, 3)System.out.println(shortNames.size())for (String s in shortNames) {

System.out.println(s)}

}}

Page 34: Make Your Builds More Groovy

...A Better Java...

ESDC 2010 - 34

© A

SE

RT

20

08

-20

10

class Erase {private List removeLongerThan(List strings, int length) {

List result = new ArrayList()for (String s in strings) {

if (s.length() <= length) {result.add(s)

}}return result

}

public static void main(String[] args) {List names = new ArrayList()names.add("Ted"); names.add("Fred")names.add("Jed"); names.add("Ned")System.out.println(names)Erase e = new Erase()List shortNames = e.removeLongerThan(names, 3)System.out.println(shortNames.size())for (String s in shortNames) {

System.out.println(s)}

}}

Do we needthe static types?Must we alwayshave a mainmethod andclass definition?How aboutimprovedconsistency?

Page 35: Make Your Builds More Groovy

...A Better Java...

ESDC 2010 - 35

© A

SE

RT

20

08

-20

10

def removeLongerThan(strings, length) {def result = new ArrayList()for (s in strings) {

if (s.size() <= length) {result.add(s)

}}return result

}

names = new ArrayList()names.add("Ted")names.add("Fred")names.add("Jed")names.add("Ned")System.out.println(names)shortNames = removeLongerThan(names, 3)System.out.println(shortNames.size())for (s in shortNames) {

System.out.println(s)}

Page 36: Make Your Builds More Groovy

...A Better Java...

ESDC 2010 - 36

© A

SE

RT

20

08

-20

10

def removeLongerThan(strings, length) {def result = new ArrayList()for (s in strings) {

if (s.size() <= length) {result.add(s)

}}return result

}

names = new ArrayList()names.add("Ted")names.add("Fred")names.add("Jed")names.add("Ned")System.out.println(names)shortNames = removeLongerThan(names, 3)System.out.println(shortNames.size())for (s in shortNames) {

System.out.println(s)}

Shouldn‟t wehave specialnotation for lists? And specialfacilities forlist processing?Is „return‟needed at end?

Page 37: Make Your Builds More Groovy

...A Better Java...

ESDC 2010 - 37

© A

SE

RT

20

08

-20

10

def removeLongerThan(strings, length) {strings.findAll{ it.size() <= length }

}

names = ["Ted", "Fred", "Jed", "Ned"]System.out.println(names)shortNames = removeLongerThan(names, 3)System.out.println(shortNames.size())shortNames.each{ System.out.println(s) }

Page 38: Make Your Builds More Groovy

...A Better Java...

ESDC 2010 - 38

© A

SE

RT

20

08

-20

10

def removeLongerThan(strings, length) {strings.findAll{ it.size() <= length }

}

names = ["Ted", "Fred", "Jed", "Ned"]System.out.println(names)shortNames = removeLongerThan(names, 3)System.out.println(shortNames.size())shortNames.each{ System.out.println(s) }

Is the methodnow needed?Easier ways touse commonmethods?Are bracketsrequired here?

Page 39: Make Your Builds More Groovy

...A Better Java...

ESDC 2010 - 39

© A

SE

RT

20

08

-20

10

names = ["Ted", "Fred", "Jed", "Ned"]println namesshortNames = names.findAll{ it.size() <= 3 }println shortNames.size()shortNames.each{ println it }

Page 40: Make Your Builds More Groovy

...A Better Java

ESDC 2010 - 40

© A

SE

RT

20

08

-20

10

names = ["Ted", "Fred", "Jed", "Ned"]println namesshortNames = names.findAll{ it.size() <= 3 }println shortNames.size()shortNames.each{ println it }

[Ted, Fred, Jed, Ned]3TedJedNed

Page 41: Make Your Builds More Groovy

Topics

• Build Pain Points

• Build Tool Landscape

• Groovy Intro

Ant & friendsCalling Groovy from Ant

Calling Ant from Groovy

Gant

• Maven & friends

• Gradle

• Other Tools

• More InfoESDC 2010 - 41

© A

SE

RT

20

08

-20

10

Page 42: Make Your Builds More Groovy

What is Ant?

• Tool to assist automating (build) steps

ESDC 2010 - 42

© A

SE

RT

20

08

-20

10

<project name="MyProject" default="dist" basedir="."><property name="src" location="src"/><property name="build" location="build"/>

<target name="init"><mkdir dir="${build}"/>

</target>

<target name="compile" depends="init"description="compile the source">

<javac srcdir="${src}" destdir="${build}"/></target>

</project>

Page 43: Make Your Builds More Groovy

Groovy from Ant

• Need groovy jar on your Ant classpath

<taskdef name="groovy"classname="org.codehaus.groovy.ant.Groovy"classpathref="my.classpath"/>

<target name="printXmlFileNamesFromJar"><zipfileset id="found" src="foobar.jar"

includes="**/*.xml"/><groovy>

project.references.found.each {println it.name

} </groovy>

</target>

ESDC 2010 - 43

© A

SE

RT

20

06

-20

10

Page 44: Make Your Builds More Groovy

Groovyc from Ant

• Need groovy jar on your Ant classpath

<taskdef name="groovyc"

classname="org.codehaus.groovy.ant.Groovyc"

classpathref="my.classpath"/>

<groovyc srcdir="${testSourceDirectory}"

destdir="${testClassesDirectory}">

<classpath>

<pathelement path="${mainClassesDirectory}"/>

<pathelement path="${testClassesDirectory}"/>

<path refid="testPath"/>

</classpath>

<javac source="1.5" target="1.5" debug="on" />

</groovyc>

ESDC 2010 - 44

© A

SE

RT

20

06

-20

10

Page 45: Make Your Builds More Groovy

ESDC 2010 - 45

© A

SE

RT

20

06

-20

10

AntBuilder...def ant = new AntBuilder()

ant.echo("hello") // let's just call one task

// create a block of Ant using the builder patternant.with {

myDir = "target/AntTest/"mkdir(dir: myDir)copy(todir: myDir) {

fileset(dir: "src/test") {include(name: "**/*.groovy")

}}echo("done")

}

// now let's do some normal Groovy againfile = new File("target/test/AntTest.groovy")assert file.exists()

Needs ant.jar on your Groovy classpath

Page 46: Make Your Builds More Groovy

...AntBuilder

• Built-in

new AntBuilder().with {echo(file:'Temp.java', '''class Temp {public static void main(String[] args) {

System.out.println("Hello");}

}''')javac(srcdir:'.', includes:'Temp.java', fork:'true')java(classpath:'.', classname:'Temp', fork:'true')echo('Done')

}// =>// [javac] Compiling 1 source file// [java] Hello// [echo] Done

© A

SE

RT

20

06

-20

10

ESDC 2010 - 46

Page 47: Make Your Builds More Groovy

ESDC 2010 - 47

© A

SE

RT

20

06

-20

10

Using AntLibs: Maven Ant Tasks & AntUnitimport static groovy.xml.NamespaceBuilder.newInstance as namespacedef ant = new AntBuilder()def mvn = namespace(ant, 'antlib:org.apache.maven.artifact.ant')def antunit = namespace(ant, 'antlib:org.apache.ant.antunit')

direct = [groupId:'jfree', artifactId:'jfreechart', version:'1.0.9']indirect = [groupId:'jfree', artifactId:'jcommon', version:'1.0.12']

// download artifactsmvn.dependencies(filesetId:'artifacts') { dependency(direct) }

// print out what we downloadedant.fileScanner { fileset(refid:'artifacts') }.each { println it }

// use AntUnit to confirm expected files were downloadeddef prefix = System.properties.'user.home' + '/.m2/repository'[direct, indirect].each { item ->

def (g, a, v) = [item.groupId, item.artifactId, item.version]antunit.assertFileExists(file:"$prefix/$g/$a/$v/$a-${v}.jar")

}

C:\Users\paulk\.m2\repository\jfree\jcommon\1.0.12\jcommon-1.0.12.jarC:\Users\paulk\.m2\repository\jfree\jfreechart\1.0.9\jfreechart-1.0.9.jar

Page 48: Make Your Builds More Groovy

Builds: Gant• lightweight façade on Groovy's AntBuilder

• target def’ns, pre-defined ‘ant’, operations on

predefined objects

includeTargets << gant.targets.CleancleanPattern << [ '**/*~' , '**/*.bak' ]cleanDirectory << 'build'

target ( stuff : 'A target to do some stuff.' ) {println ( 'Stuff' )depends ( clean )echo ( message : 'A default message from Ant.' )otherStuff ( )

}

target ( otherStuff : 'A target to do some other stuff' ) {println ( 'OtherStuff' )echo ( message : 'Another message from Ant.' )clean ( )

}

ESDC 2010 - 48

© A

SE

RT

20

06

-20

10

Page 49: Make Your Builds More Groovy

Topics

• Build Pain Points

• Build Tool Landscape

• Groovy Intro

• Ant & friends

Maven & friendsWriting plugins in Groovy

Building your Groovy project

• Gradle

• Other Tools

• More Info

ESDC 2010 - 49

© A

SE

RT

20

08

-20

10

Page 50: Make Your Builds More Groovy

What is Maven?

• Tool to assist automating (build) steps

ESDC 2010 - 50

© A

SE

RT

20

08

-20

10

Page 51: Make Your Builds More Groovy

Builds: GMaven...• Implementing Maven plugins has

never been Groovier!

• Groovy Mojos

– A Simple Groovy Mojo

• Building Plugins

– Project Definition

– Mojo Parameters

• Putting More Groove into your Mojo

– Using ant, Using fail()

• gmaven-archetype-mojo Archetype

• gmaven-plugin Packaging

ESDC 2010 - 51

© A

SE

RT

20

06

-20

10

Page 52: Make Your Builds More Groovy

...Builds: GMaven...

<plugin><groupId>org.codehaus.groovy.maven</groupId><artifactId>gmaven-plugin</artifactId><executions>

<execution><phase>generate-resources</phase><goals>

<goal>execute</goal></goals><configuration>

<source>if (project.packaging != 'pom') {

log.info('Copying some stuff...')def dir = new File(project.basedir, 'target/classes/META-INF'ant.mkdir(dir: dir)ant.copy(todir: dir) {

fileset(dir: project.basedir) {include(name: 'LICENSE.txt')include(name: 'NOTICE.txt')

}}

}</source>

</configuration></execution>

</executions></plugin> ESDC 2010 - 52

© A

SE

RT

20

06

-20

10

Page 53: Make Your Builds More Groovy

...Builds: GMaven...

<plugin><groupId>org.codehaus.mojo.groovy</groupId><artifactId>groovy-maven-plugin</artifactId><executions>

<execution><id>restart-weblogic</id><phase>pre-integration-test</phase><goals>

<goal>execute</goal></goals><configuration>

<source>${pom.basedir}/src/main/script/restartWeblogic.groovy</source>

</configuration></execution>

...

ESDC 2010 - 53

© A

SE

RT

20

06

-20

10

Page 54: Make Your Builds More Groovy

...Builds: GMaven...

def domainDir =project.properties['weblogic.domain.easyimage.dir']

stopWebLogic()copyFiles(domainDir)startWebLogic(domainDir)waitForWebLogicStartup()

def stopWebLogic() {weblogicServerDir = project.properties['weblogic.server.dir']adminUrl = project.properties['easyimage.weblogic.admin.t3']userName = 'weblogic'password = 'weblogic'ant.exec(executable: 'cmd', failonerror: 'false') {

arg(line: "/C ${wlsDir}/bin/setWLSEnv.cmd && java ..." ...}

...

ESDC 2010 - 54

© A

SE

RT

20

06

-20

10

Page 55: Make Your Builds More Groovy

...Builds: GMaven

ESDC 2010 - 55

© A

SE

RT

20

06

-20

10

Page 56: Make Your Builds More Groovy

Topics

• Build Pain Points

• Build Tool Landscape

• Groovy Intro

• Ant & friends

• Maven & friends

Gradle

• Other Tools

• More Info

ESDC 2010 - 56

© A

SE

RT

20

08

-20

10

Page 57: Make Your Builds More Groovy

What is Gradle?

• Tool to assist automating (build) steps

ESDC 2010 - 57

© A

SE

RT

20

08

-20

10

task hello << {println 'Hello world!'

}

task intro(dependsOn: hello) << {println "I'm Gradle"

}

> gradle -q intro

Hello world!

I'm Gradle

Page 58: Make Your Builds More Groovy

Gradle Features• A very flexible general purpose build tool like Ant

• Switchable, build-by-convention frameworks a la Maven. But

we never lock you in!

• Very powerful support for multi-project builds

• Very powerful dependency management (based on Apache

Ivy)

• Full support for your existing Maven or Ivy repository

infrastructure

• Support for transitive dependency management without the

need for remote repositories or pom.xml and ivy.xml files

• Ant tasks as first class citizens

• Groovy build scripts

• A rich domain model for describing your build

ESDC 2010 - 58

© A

SE

RT

20

06

-20

10

Page 59: Make Your Builds More Groovy

Gradle Examples

ESDC 2010 - 59

© A

SE

RT

20

06

-20

10

Page 60: Make Your Builds More Groovy

Revisiting our Preview Example

ESDC 2010 - 60

© A

SE

RT

20

08

-20

10

Switchingto IDE

Page 61: Make Your Builds More Groovy

Topics

• Build Pain Points

• Build Tool Landscape

• Groovy Intro

• Ant & friends

• Maven & friends

• Gradle

Other Tools

• More Info

ESDC 2010 - 61

© A

SE

RT

20

08

-20

10

Page 62: Make Your Builds More Groovy

Hudson• Gant Plugin — This plugin allows Hudson to invoke

Gant build script as the main build step

• Gradle Plugin — This plugin allows Hudson to invoke

Gradle build script as the main build step

• Grails Plugin — This plugin allows Hudson to invoke

Grails tasks as build steps

• Hudson CLI and GroovyShell

Source: http://weblogs.java.net/blog/kohsuke/archive/2009/05/hudson_cli_and.htmlESDC 2010 - 62

© A

SE

RT

20

06

-20

10

Page 63: Make Your Builds More Groovy

Hudson: Groovy Postbuild Plugin...

Source: http://wiki.hudson-ci.org/display/HUDSON/Groovy+Postbuild+Plugin

if (manager.logContains(".*uses or overrides a deprecated API.*")) {manager.addWarningBadge("Thou shalt not use deprecated methods.")manager.createSummary("warning.gif").appendText(

"<h1>You have been warned!</h1>", false, false, false, "red")manager.buildUnstable()

}

© A

SE

RT

20

06

-20

10

Page 64: Make Your Builds More Groovy

...Hudson: Groovy Postbuild Plugin

Adapted from: http://wiki.hudson-ci.org/display/HUDSON/Groovy+Postbuild+Plugin

regex = 'src/main/java/(.*).java:[^ ]* (.*) is Sun proprietary API and may be removed in a future release'map = [:]manager.build.logFile.eachMatch(regex) { full, ownClass, sunClass ->

map[ownClass.replaceAll("/", ".")] = sunClass}if (map) {

manager.createSummary("warning.gif").with {appendText("Classes using Sun proprietary API:<ul>", false)map.each { k, v ->

appendText("<li><b>$k</b> - uses $v</li>", false) }appendText("</ul>", false)

}}

© A

SE

RT

20

06

-20

10

Page 65: Make Your Builds More Groovy

Topics

• Build Pain Points

• Build Tool Landscape

• Groovy Intro

• Ant & friends

• Maven & friends

• Gradle

• Other Tools

More Info

ESDC 2010 - 65

© A

SE

RT

20

08

-20

10

Page 66: Make Your Builds More Groovy

More Information...

ESDC 2010 - 66

© A

SE

RT

20

08

-20

10

• Ant– http://ant.apache.org

– http://groovy.codehaus.org/The+groovy+Ant+Task

– http://groovy.codehaus.org/Using+Ant+from+Groovy

– http://groovy.codehaus.org/Using+Ant+Libraries+with

+AntBuilder

– http://gant.codehaus.org/

• Maven– http://maven.apache.org

– http://gmaven.codehaus.org

• Gradle– http://gradle.org

Page 67: Make Your Builds More Groovy

...More Information...

• Groovy Web sites– http://groovy.codehaus.org

– http://grails.codehaus.org

– http://pleac.sourceforge.net/pleac_groovy (many examples)

– http://www.asert.com.au/training/java/GV110.htm (workshop)

• Groovy User Mailing list– [email protected]

• Groovy Information portals– http://www.aboutgroovy.org

– http://www.groovyblogs.org

• Groovy Documentation (1000+ pages)– Getting Started Guide, User Guide, Developer Guide, Testing Guide,

Cookbook Examples, Advanced Usage Guide

© A

SE

RT

20

06

-20

10

ESDC 2010 - 67

Page 68: Make Your Builds More Groovy

GinA 2ed “ReGinA” is coming ...

© A

SE

RT

20

06

-20

10