SlideShare a Scribd company logo
1 of 67
Download to read offline
© ASERT 2008-2010




                    Make Your Builds More Groovy
                                 Dr Paul King
                                 paulk@asert.com.au
                                 @paulk_asert
                                 ASERT, Australia
                                                      ESDC 2010 - 1
Topics
                    Build Pain Points
                    • Build Tool Landscape
                    • Groovy Intro
                    • Ant & friends
                    • Maven & friends
© ASERT 2008-2010




                    • Gradle
                    • Other Tools
                    • More Info



                                               ESDC 2010 - 2
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
                      –
© ASERT 2008-2010




                          Many manual steps
                      –   Environment fragile
                           • different machines, CI vs IDE, dev vs prod vs test




                                                                                  ESDC 2010 - 3
...Build Pain Points...
                    • Require powerful features
                      –   Dependency management
                      –   Version management
                      –   Polyglot compilation
                      –   Artifact production and manipulation (jar, war, ...)
                      –   Templating (generation of boilerplate text files)
© ASERT 2008-2010




                      –   Multifacted testing
                      –   Reporting
                      –   Quality control (Metrics, code quality, static analysis)
                      –   Property management
                      –   Infinitely(?) extensible



                                                                             ESDC 2010 - 4
...Build Pain Points
                    • Useful characteristics
                      –   Tool friendly
                      –   Cross platform
                      –   IDE support, CI support
                      –   Refactorable
                      –   Testable
© ASERT 2008-2010




                      –   Minimal noise (DSL like)
                      –   Easy to extend
                      –   Conventions
                      –   Good documentation
                      –   Polyglot friendly



                                                           ESDC 2010 - 5
Topics
                    • Build Pain Points
                    Build Tool Landscape
                    • Groovy Intro
                    • Ant & friends
                    • Maven & friends
© ASERT 2008-2010




                    • Gradle
                    • Other Tools
                    • More Info



                                             ESDC 2010 - 6
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
© ASERT 2008-2010




                      – 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
Pros/Cons of Traditional Tools
                    • Ant                           • Maven
                      – Flexible (supports any        – Opinionated about
                        convention)                     conventions
                      – Easy to extend                   • Mostly a good thing
                      – Wealth of useful tasks        – Mostly declarative
                      – Well documented                  • XML != concise DSL
                                                      – Numerous plugins
© ASERT 2008-2010




                      – Partially declarative but
                        some scope for                – Some easy extension
                        procedural instructions         points but some more
                         • XML != prog. language        difficult options
                      – Lifecycle is hand-crafted        • Some things beyond
                                                           some teams
                        in your build file
                                                      – Structured lifecycle
                      – Can use Ivy or Maven Ant
                        tasks for dependency
                        management
                                                                           ESDC 2010 - 8
Enhancing Traditional Tools
                    • Ant + Groovy                 • Maven + Groovy
                      – Easy to write the            – Easier to extend
                        procedural pieces            – More concise syntax
                      – Easier to refactor           – Some scope for
                      – Easier to test                 refactoring
                      – Ease of creating a build
© ASERT 2008-2010




                        DSL
                      – More concise
                      – Better interaction with    • Gradle
                        Java                         – Take the best of both
                      – No impedence                   worlds and combine
                        mismatch with                  them
                        developers


                                                                        ESDC 2010 - 9
A Preview Example...
© ASERT 2008-2010




                                           ESDC 2010 - 10
...A Preview Example...
                              StringUtils: Vanilla Ant + Ivy
                    <project name="StringUtilsBuild" default="package"                                    <?xml version="1.0" encoding="ISO-8859-1"?>
                             xmlns:ivy="antlib:org.apache.ivy.ant" xmlns="antlib:org.apache.tools.ant">
                        <target name="clean">
                                                                                                          <ivy-module version="1.0">
                            <delete dir="target"/>                                                          <info organisation="org" module="groovycookbook" />
                            <delete dir="lib"/>                                                             <dependencies>
                        </target>                                                                             <dependency name="junit" rev="4.7" />
                       <target name="compile" depends="-init-ivy">                                          </dependencies>
                           <mkdir dir="target/classes"/>                                                  </ivy-module>
                           <javac srcdir="src/main"
                                  destdir="target/classes"/>
                       </target>

                       <target name="compileTest" depends="compile">
                           <mkdir dir="target/test-classes"/>                                             <ivysettings>
                           <javac srcdir="src/test"                                                         <settings defaultResolver="chained"/>
                                  destdir="target/test-classes">                                            <resolvers>
                               <classpath>                                                                    <chain name="chained" returnFirst="true">
                                    <pathelement location="target/classes"/>                                    <ibiblio name="ibiblio" />
                                    <fileset dir="lib" includes="*.jar"/>
                                                                                                                <url name="ibiblio-mirror">
                               </classpath>
                           </javac>                                                                               <artifact
                       </target>                                                                          pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/
© ASERT 2008-2010




                                                                                                                     [module]/[branch]/[revision]/[branch]-[revision].[ext]" />
                       <target name="test" depends="compileTest">                                               </url>
                           <mkdir dir="target/test-reports"/>                                                 </chain>
                           <junit printsummary="yes" fork="yes" haltonfailure="yes">                        </resolvers>
                               <classpath>
                                                                                                          </ivysettings>
                                    <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>


                                                                                                                                                                              ESDC 2010 - 11
...A Preview Example...
                               StringUtils: Groovy's AntBuilder
                                                                                                        ...
                    import static groovy.xml.NamespaceBuilder.newInstance as namespace
                                                                                                        def test() {
                    ant = new AntBuilder()                                                                  compileTest()
                    clean()                                                                                 ant.mkdir dir: 'target/test-reports'
                    doPackage()                                                                             ant.junit(printsummary: 'yes', haltonfailure: 'yes', fork: 'yes') {
                                                                                                                classpath {
                    def doPackage() {                                                                               pathelement location: 'target/classes'
                        test()                                                                                      pathelement location: 'target/test-classes'
                        ant.jar destfile: 'target/stringutils-1.0-SNAPSHOT.jar',                                    fileset dir: 'lib', includes: '*.jar'
                            basedir: 'target/classes'                                                           }
                    }                                                                                           formatter type: 'plain'
                                                                                                                formatter type: 'xml'
                    private dependencies() {                                                                    batchtest(todir: 'target/test-reports', fork: 'yes') {
                        def ivy_version = '2.1.0-rc2'                                                               fileset dir: 'target/test-classes'
                        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',
© ASERT 2008-2010




                                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()                                                                  <?xml version="1.0" encoding="ISO-8859-1"?>
                    }                                                                                   <ivy-module version="1.0">
                                                                                                          <info organisation="org" module="groovycookbook" />
                    def clean() {                                                                         <dependencies>
                        ant.delete dir: 'target'
                        ant.delete dir: 'lib'
                                                                                                            <dependency name="junit" rev="4.7" />
                    }                                                                                     </dependencies>
                                                                                                        </ivy-module>
                    def compile() {
                        dependencies()
                        ant.mkdir dir: 'target/classes'
                        ant.javac destdir: 'target/classes', srcdir: 'src/main',                      <ivysettings>
                            includeantruntime: false                                                    <settings defaultResolver="chained"/>
                    }                                                                                   <resolvers>
                                                                                                          <chain name="chained" returnFirst="true">
                    def compileTest() {                                                                     <ibiblio name="ibiblio" />
                        compile()                                                                           <url name="ibiblio-mirror">
                        ant.mkdir dir: 'target/test-classes'                                                  <artifact
                        ant.javac(destdir: 'target/test-classes', srcdir: 'src/test',                 pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/
                            includeantruntime: false) {                                                          [module]/[branch]/[revision]/[branch]-[revision].[ext]" />
                            classpath {                                                                     </url>
                                pathelement location: 'target/classes'                                    </chain>
                                fileset dir: 'lib', includes: '*.jar'                                   </resolvers>
                            }                                                                         </ivysettings>
                        }
                    }
                    ...




                                                                                                                                                                    ESDC 2010 - 12
...A Preview Example...
                               StringUtils: Gant
                                                                                                     ...
                    import static groovy.xml.NamespaceBuilder.newInstance as namespace
                                                                                                     target(test: '') {
                    target('package': '') {                                                              depends 'compileTest'
                        depends 'test'                                                                   mkdir dir: 'target/test-reports'
                        jar destfile: 'target/stringutils-1.0-SNAPSHOT.jar',                             junit(printsummary: 'yes', haltonfailure: 'yes', fork: 'yes') {
                            basedir: 'target/classes'                                                        classpath {
                    }                                                                                            pathelement location: 'target/classes'
                                                                                                                 pathelement location: 'target/test-classes'
                    target('-download-ivy': '') {                                                                fileset dir: 'lib', includes: '*.jar'
                        def ivy_version = '2.1.0-rc2'                                                        }
                        def repo = 'http://repo2.maven.org/maven2'                                           formatter type: 'plain'
                        mkdir dir: 'lib'                                                                     formatter type: 'xml'
                        get dest: 'lib/ivy.jar',                                                             batchtest(todir: 'target/test-reports', fork: 'yes') {
                            usetimestamp: 'true',                                                                fileset dir: 'target/test-classes'
                            src: "$repo/org/apache/ivy/ivy/$ivy_version/ivy-${ivy_version}.jar"              }
                    }                                                                                    }
                                                                                                     }
                    target(clean: '') {
                        delete dir: 'target'                                                         setDefaultTarget 'package'
                        delete dir: 'lib'
© ASERT 2008-2010




                    }

                    target(compile: '') {
                        depends '-init-ivy'
                        mkdir dir: 'target/classes'                                                 <?xml version="1.0" encoding="ISO-8859-1"?>
                        javac destdir: 'target/classes', srcdir: 'src/main'                         <ivy-module version="1.0">
                    }                                                                                 <info organisation="org" module="groovycookbook" />
                                                                                                      <dependencies>
                    target('-init-ivy': '') {
                        depends '-download-ivy'
                                                                                                        <dependency name="junit" rev="4.7" />
                        taskdef classpath: 'lib/ivy.jar',                                             </dependencies>
                                uri: 'antlib:org.apache.ivy.ant',                                   </ivy-module>
                                resource: 'org/apache/ivy/ant/antlib.xml'
                        def ivy = namespace(ant, 'antlib:org.apache.ivy.ant')
                        ivy.settings file: 'ivysettings.xml'
                        ivy.retrieve()                                                            <ivysettings>
                    }                                                                               <settings defaultResolver="chained"/>
                                                                                                    <resolvers>
                    target(compileTest: '') {                                                         <chain name="chained" returnFirst="true">
                        depends 'compile'                                                               <ibiblio name="ibiblio" />
                        mkdir dir: 'target/test-classes'                                                <url name="ibiblio-mirror">
                        javac(destdir: 'target/test-classes', srcdir: 'src/test') {                       <artifact
                            classpath {                                                           pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/
                                pathelement location: 'target/classes'                                       [module]/[branch]/[revision]/[branch]-[revision].[ext]" />
                                fileset dir: 'lib', includes: '*.jar'                                   </url>
                            }                                                                         </chain>
                        }                                                                           </resolvers>
                    }                                                                             </ivysettings>
                    ...




                                                                                                                                                                ESDC 2010 - 13
...A Preview Example...
                          StringUtils: Maven
                    <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>
© ASERT 2008-2010




                            <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>
                                                                                      ESDC 2010 - 14
...A Preview Example
                    StringUtils: Gradle


                      usePlugin 'java'

                      sourceCompatibility = 1.5
                      version = '1.0-SNAPSHOT'

                      repositories {
© ASERT 2008-2010




                          mavenCentral()
                      }

                      dependencies {
                          testCompile 'junit:junit:4.7'
                      }




                                                          ESDC 2010 - 15
Topics
                    • Build Pain Points
                    • Build Tool Landscape
                    Groovy Intro
                    • Ant & friends
                    • Maven & friends
© ASERT 2008-2010




                    • Gradle
                    • Other Tools
                    • More Info



                                               ESDC 2010 - 16
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.”
© ASERT 2008-2010




                    Groovy = Java –    boiler plate code
                                  +    optional dynamic typing
                                  +    closures
                                  +    domain specific languages
                                  +    builders
                                  +    metaprogramming
                                  +    GDK library
                                                                ESDC 2010 - 17
Groovy Goodies Overview
                    • Fully object oriented
                    • Closures: reusable
                      and assignable
                      pieces of code
                    • Operators can be          • GPath: efficient
                      overloaded
© ASERT 2008-2010




                                                  object navigation
                    • Multimethods              • GroovyBeans
                    • Literal declaration for   • grep and switch
                      lists (arrays), maps,
                      ranges and regular        • Templates, builder,
                      expressions                 swing, Ant, markup,
                                                  XML, SQL, XML-RPC,
                                                  Scriptom, Grails,
                                                  tests, Mocks  ESDC 2010 - 18
Growing Acceptance …
  A slow and steady start but now gaining in
  momentum, maturity and mindshare




Now free
… Growing Acceptance …
© ASERT 2008-2010




                                             ESDC 2010 - 20
… Growing Acceptance …
© ASERT 2008-2010




                      Groovy and Grails downloads:
                      70-90K per month and growing
                                                     ESDC 2010 - 21
… Growing Acceptance …
© ASERT 2008-2010




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




                                                      Source: http://www.grailspodcast.co
                                                                                        ESDC 2010 - 22
… Growing Acceptance …
© ASERT 2008-2010




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




                                                      http://www.java.net   ESDC 2010 - 23
… Growing Acceptance
© ASERT 2006-2010




                     http://pollpigeon.com/jsf-grails-wicket/r/25665/
                                                                        ESDC 2010 - 24
… Growing Acceptance …
         What alternative JVM language are you using or intending to use
© ASERT 2008-2010




                           http://www.leonardoborges.com/writings
                                                                    ESDC 2010 - 25
… Growing Acceptance …
© ASERT 2008-2010




                    http://it-republik.de/jaxenter/quickvote/results/1/poll/44 (translated using http://babelfish.yahoo
                                                                                                         ESDC 2010 - 26
… Growing Acceptance
© ASERT 2008-2010




                                           ESDC 2010 - 27
The Landscape of JVM Languages

                                                                                                                 mostly
                                                                                                                dynamic
                                                                                                                  typing
© ASERT 2008-2010




                                       Dynamic features call
                                       for dynamic types                                   Java bytecode calls
                                                                                               for static types




                    The terms “Java Virtual Machine” and “JVM” mean a Virtual Machine for the Java™ platform.
                                                                                                                     ESDC 2010 - 28
Groovy Starter
                    System.out.println("Hello, World!");   // optional semicolon,
                    println 'Hello, World!'                // System.out, brackets,
                                                           // main() method, class defn

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

                    String longer = """${name}, the car
                    is in the next row."""                 // multi-line string
                                                           // with static typing
© ASERT 2008-2010




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

                    def printSize(obj) {                   // optional duck typing
                        print obj?.size()                  // safe dereferencing
                    }

                    def pets = ['ant', 'bee', 'cat']       //   native list syntax
                    pets.each { pet ->                     //   closure support
                        assert pet < 'dog'                 //   overloading '<' on String
                    }                                      //   or: for (pet in pets)...




                                                                                            ESDC 2010 - 29
A Better Java...
                    import java.util.List;
                    import java.util.ArrayList;

                    class Erase {
                        private List removeLongerThan(List strings, int length) {   This code
                            List result = new ArrayList();
                            for (int i = 0; i < strings.size(); i++) {              is valid
                                String s = (String) strings.get(i);
                                if (s.length() <= length) {                         Java and
                                }
                                    result.add(s);                                  valid Groovy
                            }
                            return result;
© ASERT 2008-2010




                        }
                        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();                                   Based on an
                            List shortNames = e.removeLongerThan(names, 3);
                            System.out.println(shortNames.size());                   example by
                            for (int i = 0; i < shortNames.size(); i++) {            Jim Weirich
                                String s = (String) shortNames.get(i);
                                System.out.println(s);                               & Ted Leung
                            }
                        }
                    }



                                                                                          ESDC 2010 - 30
...A Better Java...
                    import java.util.List;
                    import java.util.ArrayList;

                    class Erase {
                        private List removeLongerThan(List strings, int length) {   Do the
                            List result = new ArrayList();
                            for (int i = 0; i < strings.size(); i++) {              semicolons
                                String s = (String) strings.get(i);
                                if (s.length() <= length) {                         add anything?
                                }
                                    result.add(s);                                  And shouldn‟t
                            }                                                       we us more
                            return result;
© ASERT 2008-2010




                        }                                                           modern list
                        public static void main(String[] args) {
                            List names = new ArrayList();                           notation?
                            names.add("Ted"); names.add("Fred");
                            names.add("Jed"); names.add("Ned");
                                                                                    Why not
                            System.out.println(names);                              import common
                            Erase e = new Erase();
                            List shortNames = e.removeLongerThan(names, 3);         libraries?
                            System.out.println(shortNames.size());
                            for (int i = 0; i < shortNames.size(); i++) {
                                String s = (String) shortNames.get(i);
                                System.out.println(s);
                            }
                        }
                    }



                                                                                          ESDC 2010 - 31
...A Better Java...
                    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()
© ASERT 2008-2010




                            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)
                            }
                        }
                    }




                                                                                    ESDC 2010 - 32
...A Better Java...
                    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)                                   Do we need
                                }
                            }                                                       the static types?
                        }
                            return result                                           Must we always
                                                                                    have a main
                        public static void main(String[] args) {
                            List names = new ArrayList()                            method and
© ASERT 2008-2010




                            names.add("Ted"); names.add("Fred")
                            names.add("Jed"); names.add("Ned")                      class definition?
                            System.out.println(names)
                            Erase e = new Erase()
                                                                                    How about
                            List shortNames = e.removeLongerThan(names, 3)          improved
                            System.out.println(shortNames.size())
                            for (String s in shortNames) {                          consistency?
                                System.out.println(s)
                            }
                        }
                    }




                                                                                             ESDC 2010 - 33
...A Better Java...
                    def removeLongerThan(strings, length) {
                        def result = new ArrayList()
                        for (s in strings) {
                            if (s.size() <= length) {
                                result.add(s)
                            }
                        }
                        return result
                    }
© ASERT 2008-2010




                    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)
                    }




                                                              ESDC 2010 - 34
...A Better Java...
                    def removeLongerThan(strings, length) {
                        def result = new ArrayList()
                        for (s in strings) {
                            if (s.size() <= length) {
                                result.add(s)                 Shouldn‟t we
                            }
                        }                                     have special
                        return result                         notation for lists?
                    }
                                                              And special
© ASERT 2008-2010




                    names = new ArrayList()                   facilities for
                    names.add("Ted")
                    names.add("Fred")
                                                              list processing?
                    names.add("Jed")                           Is „return‟
                    names.add("Ned")                          needed at end?
                    System.out.println(names)
                    shortNames = removeLongerThan(names, 3)
                    System.out.println(shortNames.size())
                    for (s in shortNames) {
                        System.out.println(s)
                    }




                                                                            ESDC 2010 - 35
...A Better Java...
                    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) }
© ASERT 2008-2010




                                                                 ESDC 2010 - 36
...A Better Java...
                    def removeLongerThan(strings, length) {
                        strings.findAll{ it.size() <= length }
                    }
                                                                 Is the method
                    names = ["Ted", "Fred", "Jed", "Ned"]        now needed?
                    System.out.println(names)
                    shortNames = removeLongerThan(names, 3)      Easier ways to
                    System.out.println(shortNames.size())        use common
                    shortNames.each{ System.out.println(s) }
                                                                 methods?
© ASERT 2008-2010




                                                                 Are brackets
                                                                 required here?




                                                                         ESDC 2010 - 37
...A Better Java...
                    names = ["Ted", "Fred", "Jed", "Ned"]
                    println names
                    shortNames = names.findAll{ it.size() <= 3 }
                    println shortNames.size()
                    shortNames.each{ println it }
© ASERT 2008-2010




                                                                   ESDC 2010 - 38
...A Better Java
                    names = ["Ted", "Fred", "Jed", "Ned"]
                    println names
                    shortNames = names.findAll{ it.size() <= 3 }
                    println shortNames.size()
                    shortNames.each{ println it }
© ASERT 2008-2010




                          [Ted, Fred, Jed, Ned]
                          3
                          Ted
                          Jed
                          Ned


                                                                   ESDC 2010 - 39
Topics
                    • Build Pain Points
                    • Build Tool Landscape
                    • Groovy Intro
                    Ant & friends
                         Calling Groovy from Ant
© ASERT 2008-2010




                         Calling Ant from Groovy
                         Gant
                    •   Maven & friends
                    •   Gradle
                    •   Other Tools
                    •   More Info
                                                     ESDC 2010 - 40
What is Ant?
                    • Tool to assist automating (build) steps

                    <project name="MyProject" default="dist" basedir=".">
                      <property name="src" location="src"/>
                      <property name="build" location="build"/>
© ASERT 2008-2010




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

                     <target name="compile" depends="init"
                           description="compile the source">
                       <javac srcdir="${src}" destdir="${build}"/>
                     </target>

                    </project>

                                                                     ESDC 2010 - 41
Groovy from Ant
                    • Need groovy jar on your Ant classpath

                     <taskdef name="groovy"
                              classname="org.codehaus.groovy.ant.Groovy"
                              classpathref="my.classpath"/>
© ASERT 2006-2010




                     <target name="printXmlFileNamesFromJar">
                       <zipfileset id="found" src="foobar.jar"
                                 includes="**/*.xml"/>
                       <groovy>
                         project.references.found.each {
                             println it.name
                         }
                       </groovy>
                     </target>


                                                                     ESDC 2010 - 42
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}"
© ASERT 2006-2010




                         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 - 43
AntBuilder...
                      def ant = new AntBuilder()

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

                      // create a block of Ant using the builder pattern
                      ant.with {
                          myDir = "target/AntTest/"
                          mkdir(dir: myDir)
© ASERT 2006-2010




                          copy(todir: myDir) {
                              fileset(dir: "src/test") {
                                  include(name: "**/*.groovy")
                              }
                          }
                          echo("done")
                      }

                      // now let's do some normal Groovy again
                      file = new File("target/test/AntTest.groovy")
                      assert file.exists()
                Needs ant.jar on your Groovy classpath                             ESDC 2010 - 44
...AntBuilder
                    • Built-in
                    new AntBuilder().with {
                        echo(file:'Temp.java', '''
                        class Temp {
                          public static void main(String[] args) {
                             System.out.println("Hello");
                          }
© ASERT 2006-2010




                        }
                        ''')
                        javac(srcdir:'.', includes:'Temp.java', fork:'true')
                        java(classpath:'.', classname:'Temp', fork:'true')
                        echo('Done')
                    }
                    // =>
                    //    [javac] Compiling 1 source file
                    //      [java] Hello
                    //      [echo] Done

                                                                      ESDC 2010 - 45
Using AntLibs: Maven Ant Tasks & AntUnit
                     import static groovy.xml.NamespaceBuilder.newInstance as namespace
                     def 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 artifacts
                     mvn.dependencies(filesetId:'artifacts') { dependency(direct) }
© ASERT 2006-2010




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

                     // use AntUnit to confirm expected files were downloaded
                     def 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:Userspaulk.m2repositoryjfreejcommon1.0.12jcommon-1.0.12.jar
                    C:Userspaulk.m2repositoryjfreejfreechart1.0.9jfreechart-1.0.9.jar
                                                                                                ESDC 2010 - 46
Builds: Gant
                    • lightweight façade on Groovy's AntBuilder
                    • target def’ns, pre-defined ‘ant’, operations on
                      predefined objects

                     includeTargets << gant.targets.Clean
                     cleanPattern << [ '**/*~' , '**/*.bak' ]
                     cleanDirectory << 'build'
© ASERT 2006-2010




                     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 - 47
Topics
                    • Build Pain Points
                    • Build Tool Landscape
                    • Groovy Intro
                    • Ant & friends
                    Maven & friends
© ASERT 2008-2010




                       Writing plugins in Groovy
                       Building your Groovy project
                    • Gradle
                    • Other Tools
                    • More Info

                                                       ESDC 2010 - 48
What is Maven?
                    • Tool to assist automating (build) steps
© ASERT 2008-2010




                                                            ESDC 2010 - 49
Builds: GMaven...
                    • Implementing Maven plugins has
                      never been Groovier!
                    • Groovy Mojos
                      – A Simple Groovy Mojo
                    • Building Plugins
                      – Project Definition
© ASERT 2006-2010




                      – Mojo Parameters
                    • Putting More Groove into your Mojo
                      – Using ant, Using fail()
                    • gmaven-archetype-mojo Archetype
                    • gmaven-plugin Packaging



                                                           ESDC 2010 - 50
...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>
© ASERT 2006-2010




                                 <source>
                                     if (project.packaging != 'pom') {
                                         log.info('Copying some stuff...')
                                         def dir = new File(project.basedir, 'target/classes/META-IN
                                         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 - 51
...Builds: GMaven...


                     <plugin>
                        <groupId>org.codehaus.mojo.groovy</groupId>
                        <artifactId>groovy-maven-plugin</artifactId>
                        <executions>
                           <execution>
                              <id>restart-weblogic</id>
© ASERT 2006-2010




                              <phase>pre-integration-test</phase>
                              <goals>
                                 <goal>execute</goal>
                              </goals>
                              <configuration>
                                 <source>
                                 ${pom.basedir}/src/main/script/restartWeblogic.groovy
                                 </source>
                              </configuration>
                           </execution>
                    ...




                                                                                  ESDC 2010 - 52
...Builds: GMaven...


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

                    stopWebLogic()
                    copyFiles(domainDir)
                    startWebLogic(domainDir)
© ASERT 2006-2010




                    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 - 53
...Builds: GMaven
© ASERT 2006-2010




                                        ESDC 2010 - 54
Topics
                    • Build Pain Points
                    • Build Tool Landscape
                    • Groovy Intro
                    • Ant & friends
                    • Maven & friends
© ASERT 2008-2010




                    Gradle
                    • Other Tools
                    • More Info



                                               ESDC 2010 - 55
What is Gradle?
                    • Tool to assist automating (build) steps

                          task hello << {
                              println 'Hello world!'
                          }

                          task intro(dependsOn: hello) << {
© ASERT 2008-2010




                              println "I'm Gradle"
                          }


                         > gradle -q intro
                         Hello world!
                         I'm Gradle



                                                              ESDC 2010 - 56
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
© ASERT 2006-2010




                      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 - 57
Gradle Examples
© ASERT 2006-2010




                                      ESDC 2010 - 58
Revisiting our Preview Example

                                               Switching
                                               to IDE
© ASERT 2008-2010




                                                     ESDC 2010 - 59
Topics
                    • Build Pain Points
                    • Build Tool Landscape
                    • Groovy Intro
                    • Ant & friends
                    • Maven & friends
© ASERT 2008-2010




                    • Gradle
                    Other Tools
                    • More Info



                                               ESDC 2010 - 60
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
© ASERT 2006-2010




                     • Hudson CLI and GroovyShell




                    Source: http://weblogs.java.net/blog/kohsuke/archive/2009/05/hudson_cli_and.html   ESDC 2010 - 61
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()
                    }
© ASERT 2006-2010




                Source: http://wiki.hudson-ci.org/display/HUDSON/Groovy+Postbuild+Plugin
...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)
© ASERT 2006-2010




                            }
                            appendText("</ul>", false)
                        }
                    }




                Adapted from: http://wiki.hudson-ci.org/display/HUDSON/Groovy+Postbuild+Plugin
Topics
                    • Build Pain Points
                    • Build Tool Landscape
                    • Groovy Intro
                    • Ant & friends
                    • Maven & friends
© ASERT 2008-2010




                    • Gradle
                    • Other Tools
                    More Info



                                               ESDC 2010 - 64
More Information...
                    • 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
© ASERT 2008-2010




                      – http://gant.codehaus.org/
                    • Maven
                      – http://maven.apache.org
                      – http://gmaven.codehaus.org
                    • Gradle
                      – http://gradle.org

                                                                     ESDC 2010 - 65
...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
                      – user@groovy.codehaus.org
© ASERT 2006-2010




                    • 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



                                                                                       ESDC 2010 - 66
GinA 2ed “ReGinA” is coming ...
© ASERT 2006-2010

More Related Content

Viewers also liked

Final Marco Solekai Coffee 2 For Posting
Final Marco Solekai Coffee 2 For PostingFinal Marco Solekai Coffee 2 For Posting
Final Marco Solekai Coffee 2 For PostingMarco Thompson
 
Final Martin Coffee March 4 2010 For Posting
Final Martin Coffee March 4 2010 For PostingFinal Martin Coffee March 4 2010 For Posting
Final Martin Coffee March 4 2010 For PostingMarco Thompson
 
Wind River Chumby Motorola Stacatto
Wind River   Chumby   Motorola   StacattoWind River   Chumby   Motorola   Stacatto
Wind River Chumby Motorola StacattoMarco Thompson
 
Solekai Digital Living Pitch
Solekai Digital Living PitchSolekai Digital Living Pitch
Solekai Digital Living PitchMarco Thompson
 
Linked in training 10.0
Linked in training 10.0Linked in training 10.0
Linked in training 10.0Marco Thompson
 
VIP Roundtable - Medical Devices
VIP Roundtable - Medical DevicesVIP Roundtable - Medical Devices
VIP Roundtable - Medical DevicesMarco Thompson
 
Ipsos&ISC - New media usage summary report 2013
Ipsos&ISC - New media usage summary report 2013Ipsos&ISC - New media usage summary report 2013
Ipsos&ISC - New media usage summary report 2013Nikola Jovanovic
 
Nikola Jovanovic - Eh, da mi je neko ovo rekao pre 15 godina.
Nikola Jovanovic - Eh, da mi je neko ovo rekao pre 15 godina.Nikola Jovanovic - Eh, da mi je neko ovo rekao pre 15 godina.
Nikola Jovanovic - Eh, da mi je neko ovo rekao pre 15 godina.Nikola Jovanovic
 
Emocionalna inteligencija & Lideri
Emocionalna inteligencija & LideriEmocionalna inteligencija & Lideri
Emocionalna inteligencija & LideriNikola Jovanovic
 
Verimatrix Digital Living
Verimatrix Digital LivingVerimatrix Digital Living
Verimatrix Digital LivingMarco Thompson
 
Rob Hoffman\'s Wind River Slides
Rob Hoffman\'s Wind River SlidesRob Hoffman\'s Wind River Slides
Rob Hoffman\'s Wind River SlidesMarco Thompson
 
Aero & Defense - VIP Coffee with Gene Ray - Wind River Overview
Aero & Defense - VIP Coffee with Gene Ray - Wind River OverviewAero & Defense - VIP Coffee with Gene Ray - Wind River Overview
Aero & Defense - VIP Coffee with Gene Ray - Wind River OverviewMarco Thompson
 

Viewers also liked (14)

Final Marco Solekai Coffee 2 For Posting
Final Marco Solekai Coffee 2 For PostingFinal Marco Solekai Coffee 2 For Posting
Final Marco Solekai Coffee 2 For Posting
 
Innovive April 09
Innovive April 09Innovive April 09
Innovive April 09
 
Ultrastar Damon Rubio
Ultrastar Damon RubioUltrastar Damon Rubio
Ultrastar Damon Rubio
 
Final Martin Coffee March 4 2010 For Posting
Final Martin Coffee March 4 2010 For PostingFinal Martin Coffee March 4 2010 For Posting
Final Martin Coffee March 4 2010 For Posting
 
Wind River Chumby Motorola Stacatto
Wind River   Chumby   Motorola   StacattoWind River   Chumby   Motorola   Stacatto
Wind River Chumby Motorola Stacatto
 
Solekai Digital Living Pitch
Solekai Digital Living PitchSolekai Digital Living Pitch
Solekai Digital Living Pitch
 
Linked in training 10.0
Linked in training 10.0Linked in training 10.0
Linked in training 10.0
 
VIP Roundtable - Medical Devices
VIP Roundtable - Medical DevicesVIP Roundtable - Medical Devices
VIP Roundtable - Medical Devices
 
Ipsos&ISC - New media usage summary report 2013
Ipsos&ISC - New media usage summary report 2013Ipsos&ISC - New media usage summary report 2013
Ipsos&ISC - New media usage summary report 2013
 
Nikola Jovanovic - Eh, da mi je neko ovo rekao pre 15 godina.
Nikola Jovanovic - Eh, da mi je neko ovo rekao pre 15 godina.Nikola Jovanovic - Eh, da mi je neko ovo rekao pre 15 godina.
Nikola Jovanovic - Eh, da mi je neko ovo rekao pre 15 godina.
 
Emocionalna inteligencija & Lideri
Emocionalna inteligencija & LideriEmocionalna inteligencija & Lideri
Emocionalna inteligencija & Lideri
 
Verimatrix Digital Living
Verimatrix Digital LivingVerimatrix Digital Living
Verimatrix Digital Living
 
Rob Hoffman\'s Wind River Slides
Rob Hoffman\'s Wind River SlidesRob Hoffman\'s Wind River Slides
Rob Hoffman\'s Wind River Slides
 
Aero & Defense - VIP Coffee with Gene Ray - Wind River Overview
Aero & Defense - VIP Coffee with Gene Ray - Wind River OverviewAero & Defense - VIP Coffee with Gene Ray - Wind River Overview
Aero & Defense - VIP Coffee with Gene Ray - Wind River Overview
 

Similar to make builds groovy

How To Make Your Testing More Groovy
How To Make Your Testing More GroovyHow To Make Your Testing More Groovy
How To Make Your Testing More GroovyCraig Smith
 
Lessons Learned: Novell Open Enterprise Server Upgrades Made Easy
Lessons Learned: Novell Open Enterprise Server Upgrades Made EasyLessons Learned: Novell Open Enterprise Server Upgrades Made Easy
Lessons Learned: Novell Open Enterprise Server Upgrades Made EasyNovell
 
Paulking dlp
Paulking dlpPaulking dlp
Paulking dlpd0nn9n
 
Achieving genuine elastic multitenancy with the Waratek Cloud VM for Java : J...
Achieving genuine elastic multitenancy with the Waratek Cloud VM for Java : J...Achieving genuine elastic multitenancy with the Waratek Cloud VM for Java : J...
Achieving genuine elastic multitenancy with the Waratek Cloud VM for Java : J...JAX London
 
Groovy Testing Aug2009
Groovy Testing Aug2009Groovy Testing Aug2009
Groovy Testing Aug2009guest4a266c
 
Groovy Tutorial
Groovy TutorialGroovy Tutorial
Groovy TutorialPaul King
 
Smalltalk in Enterprise Applications
Smalltalk in Enterprise ApplicationsSmalltalk in Enterprise Applications
Smalltalk in Enterprise ApplicationsESUG
 
Agile Testing Practices
Agile Testing PracticesAgile Testing Practices
Agile Testing PracticesPaul King
 
Rationalize Android Development with StAnD - Clement Escoffier, akquinet
Rationalize Android Development with StAnD - Clement Escoffier, akquinetRationalize Android Development with StAnD - Clement Escoffier, akquinet
Rationalize Android Development with StAnD - Clement Escoffier, akquinetParis Open Source Summit
 
groovy and concurrency
groovy and concurrencygroovy and concurrency
groovy and concurrencyPaul King
 
Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12
Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12
Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12Puppet
 
Safe and Reliable Embedded Linux Programming: How to Get There
Safe and Reliable Embedded Linux Programming: How to Get ThereSafe and Reliable Embedded Linux Programming: How to Get There
Safe and Reliable Embedded Linux Programming: How to Get ThereAdaCore
 
Ben Pashkoff - java embedded - 24mai2011
Ben Pashkoff - java embedded - 24mai2011Ben Pashkoff - java embedded - 24mai2011
Ben Pashkoff - java embedded - 24mai2011Agora Group
 
E-GEN/iCAN
E-GEN/iCANE-GEN/iCAN
E-GEN/iCANteddi22
 
Groovy Testing Sep2009
Groovy Testing Sep2009Groovy Testing Sep2009
Groovy Testing Sep2009Paul King
 
Radovan Janecek R E S Tor S O A Pv1
Radovan  Janecek    R E S Tor S O A Pv1Radovan  Janecek    R E S Tor S O A Pv1
Radovan Janecek R E S Tor S O A Pv1SOA Symposium
 
Shannon McFarland OpenStack/Cisco Intro
Shannon McFarland OpenStack/Cisco IntroShannon McFarland OpenStack/Cisco Intro
Shannon McFarland OpenStack/Cisco IntroShannon McFarland
 
Optimizing HTML5 Sites with CQ5/WEM
Optimizing HTML5 Sites with CQ5/WEMOptimizing HTML5 Sites with CQ5/WEM
Optimizing HTML5 Sites with CQ5/WEMGabriel Walt
 
Lean Engineering. Applying Lean Principles to Building Experiences
Lean Engineering. Applying Lean Principles to Building ExperiencesLean Engineering. Applying Lean Principles to Building Experiences
Lean Engineering. Applying Lean Principles to Building ExperiencesBill Scott
 
EclipseConEurope2012 SOA - Models As Operational Documentation
EclipseConEurope2012 SOA - Models As Operational DocumentationEclipseConEurope2012 SOA - Models As Operational Documentation
EclipseConEurope2012 SOA - Models As Operational DocumentationMarc Dutoo
 

Similar to make builds groovy (20)

How To Make Your Testing More Groovy
How To Make Your Testing More GroovyHow To Make Your Testing More Groovy
How To Make Your Testing More Groovy
 
Lessons Learned: Novell Open Enterprise Server Upgrades Made Easy
Lessons Learned: Novell Open Enterprise Server Upgrades Made EasyLessons Learned: Novell Open Enterprise Server Upgrades Made Easy
Lessons Learned: Novell Open Enterprise Server Upgrades Made Easy
 
Paulking dlp
Paulking dlpPaulking dlp
Paulking dlp
 
Achieving genuine elastic multitenancy with the Waratek Cloud VM for Java : J...
Achieving genuine elastic multitenancy with the Waratek Cloud VM for Java : J...Achieving genuine elastic multitenancy with the Waratek Cloud VM for Java : J...
Achieving genuine elastic multitenancy with the Waratek Cloud VM for Java : J...
 
Groovy Testing Aug2009
Groovy Testing Aug2009Groovy Testing Aug2009
Groovy Testing Aug2009
 
Groovy Tutorial
Groovy TutorialGroovy Tutorial
Groovy Tutorial
 
Smalltalk in Enterprise Applications
Smalltalk in Enterprise ApplicationsSmalltalk in Enterprise Applications
Smalltalk in Enterprise Applications
 
Agile Testing Practices
Agile Testing PracticesAgile Testing Practices
Agile Testing Practices
 
Rationalize Android Development with StAnD - Clement Escoffier, akquinet
Rationalize Android Development with StAnD - Clement Escoffier, akquinetRationalize Android Development with StAnD - Clement Escoffier, akquinet
Rationalize Android Development with StAnD - Clement Escoffier, akquinet
 
groovy and concurrency
groovy and concurrencygroovy and concurrency
groovy and concurrency
 
Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12
Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12
Continuous Development with Jenkins - Stephen Connolly at PuppetCamp Dublin '12
 
Safe and Reliable Embedded Linux Programming: How to Get There
Safe and Reliable Embedded Linux Programming: How to Get ThereSafe and Reliable Embedded Linux Programming: How to Get There
Safe and Reliable Embedded Linux Programming: How to Get There
 
Ben Pashkoff - java embedded - 24mai2011
Ben Pashkoff - java embedded - 24mai2011Ben Pashkoff - java embedded - 24mai2011
Ben Pashkoff - java embedded - 24mai2011
 
E-GEN/iCAN
E-GEN/iCANE-GEN/iCAN
E-GEN/iCAN
 
Groovy Testing Sep2009
Groovy Testing Sep2009Groovy Testing Sep2009
Groovy Testing Sep2009
 
Radovan Janecek R E S Tor S O A Pv1
Radovan  Janecek    R E S Tor S O A Pv1Radovan  Janecek    R E S Tor S O A Pv1
Radovan Janecek R E S Tor S O A Pv1
 
Shannon McFarland OpenStack/Cisco Intro
Shannon McFarland OpenStack/Cisco IntroShannon McFarland OpenStack/Cisco Intro
Shannon McFarland OpenStack/Cisco Intro
 
Optimizing HTML5 Sites with CQ5/WEM
Optimizing HTML5 Sites with CQ5/WEMOptimizing HTML5 Sites with CQ5/WEM
Optimizing HTML5 Sites with CQ5/WEM
 
Lean Engineering. Applying Lean Principles to Building Experiences
Lean Engineering. Applying Lean Principles to Building ExperiencesLean Engineering. Applying Lean Principles to Building Experiences
Lean Engineering. Applying Lean Principles to Building Experiences
 
EclipseConEurope2012 SOA - Models As Operational Documentation
EclipseConEurope2012 SOA - Models As Operational DocumentationEclipseConEurope2012 SOA - Models As Operational Documentation
EclipseConEurope2012 SOA - Models As Operational Documentation
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfOverkill Security
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 

Recently uploaded (20)

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 

make builds groovy

  • 1. © ASERT 2008-2010 Make Your Builds More Groovy Dr Paul King paulk@asert.com.au @paulk_asert ASERT, Australia ESDC 2010 - 1
  • 2. Topics Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle • Other Tools • More Info ESDC 2010 - 2
  • 3. 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 – © ASERT 2008-2010 Many manual steps – Environment fragile • different machines, CI vs IDE, dev vs prod vs test ESDC 2010 - 3
  • 4. ...Build Pain Points... • Require powerful features – Dependency management – Version management – Polyglot compilation – Artifact production and manipulation (jar, war, ...) – Templating (generation of boilerplate text files) © ASERT 2008-2010 – Multifacted testing – Reporting – Quality control (Metrics, code quality, static analysis) – Property management – Infinitely(?) extensible ESDC 2010 - 4
  • 5. ...Build Pain Points • Useful characteristics – Tool friendly – Cross platform – IDE support, CI support – Refactorable – Testable © ASERT 2008-2010 – Minimal noise (DSL like) – Easy to extend – Conventions – Good documentation – Polyglot friendly ESDC 2010 - 5
  • 6. Topics • Build Pain Points Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle • Other Tools • More Info ESDC 2010 - 6
  • 7. 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 © ASERT 2008-2010 – 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
  • 8. Pros/Cons of Traditional Tools • Ant • Maven – Flexible (supports any – Opinionated about convention) conventions – Easy to extend • Mostly a good thing – Wealth of useful tasks – Mostly declarative – Well documented • XML != concise DSL – Numerous plugins © ASERT 2008-2010 – Partially declarative but some scope for – Some easy extension procedural instructions points but some more • XML != prog. language difficult options – Lifecycle is hand-crafted • Some things beyond some teams in your build file – Structured lifecycle – Can use Ivy or Maven Ant tasks for dependency management ESDC 2010 - 8
  • 9. Enhancing Traditional Tools • Ant + Groovy • Maven + Groovy – Easy to write the – Easier to extend procedural pieces – More concise syntax – Easier to refactor – Some scope for – Easier to test refactoring – Ease of creating a build © ASERT 2008-2010 DSL – More concise – Better interaction with • Gradle Java – Take the best of both – No impedence worlds and combine mismatch with them developers ESDC 2010 - 9
  • 10. A Preview Example... © ASERT 2008-2010 ESDC 2010 - 10
  • 11. ...A Preview Example... StringUtils: Vanilla Ant + Ivy <project name="StringUtilsBuild" default="package" <?xml version="1.0" encoding="ISO-8859-1"?> xmlns:ivy="antlib:org.apache.ivy.ant" xmlns="antlib:org.apache.tools.ant"> <target name="clean"> <ivy-module version="1.0"> <delete dir="target"/> <info organisation="org" module="groovycookbook" /> <delete dir="lib"/> <dependencies> </target> <dependency name="junit" rev="4.7" /> <target name="compile" depends="-init-ivy"> </dependencies> <mkdir dir="target/classes"/> </ivy-module> <javac srcdir="src/main" destdir="target/classes"/> </target> <target name="compileTest" depends="compile"> <mkdir dir="target/test-classes"/> <ivysettings> <javac srcdir="src/test" <settings defaultResolver="chained"/> destdir="target/test-classes"> <resolvers> <classpath> <chain name="chained" returnFirst="true"> <pathelement location="target/classes"/> <ibiblio name="ibiblio" /> <fileset dir="lib" includes="*.jar"/> <url name="ibiblio-mirror"> </classpath> </javac> <artifact </target> pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/ © ASERT 2008-2010 [module]/[branch]/[revision]/[branch]-[revision].[ext]" /> <target name="test" depends="compileTest"> </url> <mkdir dir="target/test-reports"/> </chain> <junit printsummary="yes" fork="yes" haltonfailure="yes"> </resolvers> <classpath> </ivysettings> <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> ESDC 2010 - 11
  • 12. ...A Preview Example... StringUtils: Groovy's AntBuilder ... import static groovy.xml.NamespaceBuilder.newInstance as namespace def test() { ant = new AntBuilder() compileTest() clean() ant.mkdir dir: 'target/test-reports' doPackage() ant.junit(printsummary: 'yes', haltonfailure: 'yes', fork: 'yes') { classpath { def doPackage() { pathelement location: 'target/classes' test() pathelement location: 'target/test-classes' ant.jar destfile: 'target/stringutils-1.0-SNAPSHOT.jar', fileset dir: 'lib', includes: '*.jar' basedir: 'target/classes' } } formatter type: 'plain' formatter type: 'xml' private dependencies() { batchtest(todir: 'target/test-reports', fork: 'yes') { def ivy_version = '2.1.0-rc2' fileset dir: 'target/test-classes' 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', © ASERT 2008-2010 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() <?xml version="1.0" encoding="ISO-8859-1"?> } <ivy-module version="1.0"> <info organisation="org" module="groovycookbook" /> def clean() { <dependencies> ant.delete dir: 'target' ant.delete dir: 'lib' <dependency name="junit" rev="4.7" /> } </dependencies> </ivy-module> def compile() { dependencies() ant.mkdir dir: 'target/classes' ant.javac destdir: 'target/classes', srcdir: 'src/main', <ivysettings> includeantruntime: false <settings defaultResolver="chained"/> } <resolvers> <chain name="chained" returnFirst="true"> def compileTest() { <ibiblio name="ibiblio" /> compile() <url name="ibiblio-mirror"> ant.mkdir dir: 'target/test-classes' <artifact ant.javac(destdir: 'target/test-classes', srcdir: 'src/test', pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/ includeantruntime: false) { [module]/[branch]/[revision]/[branch]-[revision].[ext]" /> classpath { </url> pathelement location: 'target/classes' </chain> fileset dir: 'lib', includes: '*.jar' </resolvers> } </ivysettings> } } ... ESDC 2010 - 12
  • 13. ...A Preview Example... StringUtils: Gant ... import static groovy.xml.NamespaceBuilder.newInstance as namespace target(test: '') { target('package': '') { depends 'compileTest' depends 'test' mkdir dir: 'target/test-reports' jar destfile: 'target/stringutils-1.0-SNAPSHOT.jar', junit(printsummary: 'yes', haltonfailure: 'yes', fork: 'yes') { basedir: 'target/classes' classpath { } pathelement location: 'target/classes' pathelement location: 'target/test-classes' target('-download-ivy': '') { fileset dir: 'lib', includes: '*.jar' def ivy_version = '2.1.0-rc2' } def repo = 'http://repo2.maven.org/maven2' formatter type: 'plain' mkdir dir: 'lib' formatter type: 'xml' get dest: 'lib/ivy.jar', batchtest(todir: 'target/test-reports', fork: 'yes') { usetimestamp: 'true', fileset dir: 'target/test-classes' src: "$repo/org/apache/ivy/ivy/$ivy_version/ivy-${ivy_version}.jar" } } } } target(clean: '') { delete dir: 'target' setDefaultTarget 'package' delete dir: 'lib' © ASERT 2008-2010 } target(compile: '') { depends '-init-ivy' mkdir dir: 'target/classes' <?xml version="1.0" encoding="ISO-8859-1"?> javac destdir: 'target/classes', srcdir: 'src/main' <ivy-module version="1.0"> } <info organisation="org" module="groovycookbook" /> <dependencies> target('-init-ivy': '') { depends '-download-ivy' <dependency name="junit" rev="4.7" /> taskdef classpath: 'lib/ivy.jar', </dependencies> uri: 'antlib:org.apache.ivy.ant', </ivy-module> resource: 'org/apache/ivy/ant/antlib.xml' def ivy = namespace(ant, 'antlib:org.apache.ivy.ant') ivy.settings file: 'ivysettings.xml' ivy.retrieve() <ivysettings> } <settings defaultResolver="chained"/> <resolvers> target(compileTest: '') { <chain name="chained" returnFirst="true"> depends 'compile' <ibiblio name="ibiblio" /> mkdir dir: 'target/test-classes' <url name="ibiblio-mirror"> javac(destdir: 'target/test-classes', srcdir: 'src/test') { <artifact classpath { pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/ pathelement location: 'target/classes' [module]/[branch]/[revision]/[branch]-[revision].[ext]" /> fileset dir: 'lib', includes: '*.jar' </url> } </chain> } </resolvers> } </ivysettings> ... ESDC 2010 - 13
  • 14. ...A Preview Example... StringUtils: Maven <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> © ASERT 2008-2010 <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> ESDC 2010 - 14
  • 15. ...A Preview Example StringUtils: Gradle usePlugin 'java' sourceCompatibility = 1.5 version = '1.0-SNAPSHOT' repositories { © ASERT 2008-2010 mavenCentral() } dependencies { testCompile 'junit:junit:4.7' } ESDC 2010 - 15
  • 16. Topics • Build Pain Points • Build Tool Landscape Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle • Other Tools • More Info ESDC 2010 - 16
  • 17. 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.” © ASERT 2008-2010 Groovy = Java – boiler plate code + optional dynamic typing + closures + domain specific languages + builders + metaprogramming + GDK library ESDC 2010 - 17
  • 18. Groovy Goodies Overview • Fully object oriented • Closures: reusable and assignable pieces of code • Operators can be • GPath: efficient overloaded © ASERT 2008-2010 object navigation • Multimethods • GroovyBeans • Literal declaration for • grep and switch lists (arrays), maps, ranges and regular • Templates, builder, expressions swing, Ant, markup, XML, SQL, XML-RPC, Scriptom, Grails, tests, Mocks ESDC 2010 - 18
  • 19. Growing Acceptance … A slow and steady start but now gaining in momentum, maturity and mindshare Now free
  • 20. … Growing Acceptance … © ASERT 2008-2010 ESDC 2010 - 20
  • 21. … Growing Acceptance … © ASERT 2008-2010 Groovy and Grails downloads: 70-90K per month and growing ESDC 2010 - 21
  • 22. … Growing Acceptance … © ASERT 2008-2010 Source: http://www.micropoll.com/akira/mpresult/501697-116746 Source: http://www.grailspodcast.co ESDC 2010 - 22
  • 23. … Growing Acceptance … © ASERT 2008-2010 http://www.jroller.com/scolebourne/entry/devoxx_2008_whitebo http://www.java.net ESDC 2010 - 23
  • 24. … Growing Acceptance © ASERT 2006-2010 http://pollpigeon.com/jsf-grails-wicket/r/25665/ ESDC 2010 - 24
  • 25. … Growing Acceptance … What alternative JVM language are you using or intending to use © ASERT 2008-2010 http://www.leonardoborges.com/writings ESDC 2010 - 25
  • 26. … Growing Acceptance … © ASERT 2008-2010 http://it-republik.de/jaxenter/quickvote/results/1/poll/44 (translated using http://babelfish.yahoo ESDC 2010 - 26
  • 27. … Growing Acceptance © ASERT 2008-2010 ESDC 2010 - 27
  • 28. The Landscape of JVM Languages mostly dynamic typing © ASERT 2008-2010 Dynamic features call for dynamic types Java bytecode calls for static types The terms “Java Virtual Machine” and “JVM” mean a Virtual Machine for the Java™ platform. ESDC 2010 - 28
  • 29. Groovy Starter System.out.println("Hello, World!"); // optional semicolon, println 'Hello, World!' // System.out, brackets, // main() method, class defn def name = 'Guillaume' // dynamic typing println "$name, I'll get the car." // GString String longer = """${name}, the car is in the next row.""" // multi-line string // with static typing © ASERT 2008-2010 assert 0.5 == 1/2 // BigDecimal equals() def printSize(obj) { // optional duck typing print obj?.size() // safe dereferencing } def pets = ['ant', 'bee', 'cat'] // native list syntax pets.each { pet -> // closure support assert pet < 'dog' // overloading '<' on String } // or: for (pet in pets)... ESDC 2010 - 29
  • 30. A Better Java... import java.util.List; import java.util.ArrayList; class Erase { private List removeLongerThan(List strings, int length) { This code List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { is valid String s = (String) strings.get(i); if (s.length() <= length) { Java and } result.add(s); valid Groovy } return result; © ASERT 2008-2010 } 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(); Based on an List shortNames = e.removeLongerThan(names, 3); System.out.println(shortNames.size()); example by for (int i = 0; i < shortNames.size(); i++) { Jim Weirich String s = (String) shortNames.get(i); System.out.println(s); & Ted Leung } } } ESDC 2010 - 30
  • 31. ...A Better Java... import java.util.List; import java.util.ArrayList; class Erase { private List removeLongerThan(List strings, int length) { Do the List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { semicolons String s = (String) strings.get(i); if (s.length() <= length) { add anything? } result.add(s); And shouldn‟t } we us more return result; © ASERT 2008-2010 } modern list public static void main(String[] args) { List names = new ArrayList(); notation? names.add("Ted"); names.add("Fred"); names.add("Jed"); names.add("Ned"); Why not System.out.println(names); import common Erase e = new Erase(); List shortNames = e.removeLongerThan(names, 3); libraries? System.out.println(shortNames.size()); for (int i = 0; i < shortNames.size(); i++) { String s = (String) shortNames.get(i); System.out.println(s); } } } ESDC 2010 - 31
  • 32. ...A Better Java... 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() © ASERT 2008-2010 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) } } } ESDC 2010 - 32
  • 33. ...A Better Java... 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) Do we need } } the static types? } return result Must we always have a main public static void main(String[] args) { List names = new ArrayList() method and © ASERT 2008-2010 names.add("Ted"); names.add("Fred") names.add("Jed"); names.add("Ned") class definition? System.out.println(names) Erase e = new Erase() How about List shortNames = e.removeLongerThan(names, 3) improved System.out.println(shortNames.size()) for (String s in shortNames) { consistency? System.out.println(s) } } } ESDC 2010 - 33
  • 34. ...A Better Java... def removeLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) } } return result } © ASERT 2008-2010 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) } ESDC 2010 - 34
  • 35. ...A Better Java... def removeLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) Shouldn‟t we } } have special return result notation for lists? } And special © ASERT 2008-2010 names = new ArrayList() facilities for names.add("Ted") names.add("Fred") list processing? names.add("Jed") Is „return‟ names.add("Ned") needed at end? System.out.println(names) shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) for (s in shortNames) { System.out.println(s) } ESDC 2010 - 35
  • 36. ...A Better Java... 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) } © ASERT 2008-2010 ESDC 2010 - 36
  • 37. ...A Better Java... def removeLongerThan(strings, length) { strings.findAll{ it.size() <= length } } Is the method names = ["Ted", "Fred", "Jed", "Ned"] now needed? System.out.println(names) shortNames = removeLongerThan(names, 3) Easier ways to System.out.println(shortNames.size()) use common shortNames.each{ System.out.println(s) } methods? © ASERT 2008-2010 Are brackets required here? ESDC 2010 - 37
  • 38. ...A Better Java... names = ["Ted", "Fred", "Jed", "Ned"] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } © ASERT 2008-2010 ESDC 2010 - 38
  • 39. ...A Better Java names = ["Ted", "Fred", "Jed", "Ned"] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } © ASERT 2008-2010 [Ted, Fred, Jed, Ned] 3 Ted Jed Ned ESDC 2010 - 39
  • 40. Topics • Build Pain Points • Build Tool Landscape • Groovy Intro Ant & friends  Calling Groovy from Ant © ASERT 2008-2010  Calling Ant from Groovy  Gant • Maven & friends • Gradle • Other Tools • More Info ESDC 2010 - 40
  • 41. What is Ant? • Tool to assist automating (build) steps <project name="MyProject" default="dist" basedir="."> <property name="src" location="src"/> <property name="build" location="build"/> © ASERT 2008-2010 <target name="init"> <mkdir dir="${build}"/> </target> <target name="compile" depends="init" description="compile the source"> <javac srcdir="${src}" destdir="${build}"/> </target> </project> ESDC 2010 - 41
  • 42. Groovy from Ant • Need groovy jar on your Ant classpath <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="my.classpath"/> © ASERT 2006-2010 <target name="printXmlFileNamesFromJar"> <zipfileset id="found" src="foobar.jar" includes="**/*.xml"/> <groovy> project.references.found.each { println it.name } </groovy> </target> ESDC 2010 - 42
  • 43. 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}" © ASERT 2006-2010 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 - 43
  • 44. AntBuilder... def ant = new AntBuilder() ant.echo("hello") // let's just call one task // create a block of Ant using the builder pattern ant.with { myDir = "target/AntTest/" mkdir(dir: myDir) © ASERT 2006-2010 copy(todir: myDir) { fileset(dir: "src/test") { include(name: "**/*.groovy") } } echo("done") } // now let's do some normal Groovy again file = new File("target/test/AntTest.groovy") assert file.exists() Needs ant.jar on your Groovy classpath ESDC 2010 - 44
  • 45. ...AntBuilder • Built-in new AntBuilder().with { echo(file:'Temp.java', ''' class Temp { public static void main(String[] args) { System.out.println("Hello"); } © ASERT 2006-2010 } ''') javac(srcdir:'.', includes:'Temp.java', fork:'true') java(classpath:'.', classname:'Temp', fork:'true') echo('Done') } // => // [javac] Compiling 1 source file // [java] Hello // [echo] Done ESDC 2010 - 45
  • 46. Using AntLibs: Maven Ant Tasks & AntUnit import static groovy.xml.NamespaceBuilder.newInstance as namespace def 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 artifacts mvn.dependencies(filesetId:'artifacts') { dependency(direct) } © ASERT 2006-2010 // print out what we downloaded ant.fileScanner { fileset(refid:'artifacts') }.each { println it } // use AntUnit to confirm expected files were downloaded def 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:Userspaulk.m2repositoryjfreejcommon1.0.12jcommon-1.0.12.jar C:Userspaulk.m2repositoryjfreejfreechart1.0.9jfreechart-1.0.9.jar ESDC 2010 - 46
  • 47. Builds: Gant • lightweight façade on Groovy's AntBuilder • target def’ns, pre-defined ‘ant’, operations on predefined objects includeTargets << gant.targets.Clean cleanPattern << [ '**/*~' , '**/*.bak' ] cleanDirectory << 'build' © ASERT 2006-2010 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 - 47
  • 48. Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends Maven & friends © ASERT 2008-2010  Writing plugins in Groovy  Building your Groovy project • Gradle • Other Tools • More Info ESDC 2010 - 48
  • 49. What is Maven? • Tool to assist automating (build) steps © ASERT 2008-2010 ESDC 2010 - 49
  • 50. Builds: GMaven... • Implementing Maven plugins has never been Groovier! • Groovy Mojos – A Simple Groovy Mojo • Building Plugins – Project Definition © ASERT 2006-2010 – Mojo Parameters • Putting More Groove into your Mojo – Using ant, Using fail() • gmaven-archetype-mojo Archetype • gmaven-plugin Packaging ESDC 2010 - 50
  • 51. ...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> © ASERT 2006-2010 <source> if (project.packaging != 'pom') { log.info('Copying some stuff...') def dir = new File(project.basedir, 'target/classes/META-IN 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 - 51
  • 52. ...Builds: GMaven... <plugin> <groupId>org.codehaus.mojo.groovy</groupId> <artifactId>groovy-maven-plugin</artifactId> <executions> <execution> <id>restart-weblogic</id> © ASERT 2006-2010 <phase>pre-integration-test</phase> <goals> <goal>execute</goal> </goals> <configuration> <source> ${pom.basedir}/src/main/script/restartWeblogic.groovy </source> </configuration> </execution> ... ESDC 2010 - 52
  • 53. ...Builds: GMaven... def domainDir = project.properties['weblogic.domain.easyimage.dir'] stopWebLogic() copyFiles(domainDir) startWebLogic(domainDir) © ASERT 2006-2010 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 - 53
  • 54. ...Builds: GMaven © ASERT 2006-2010 ESDC 2010 - 54
  • 55. Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 Gradle • Other Tools • More Info ESDC 2010 - 55
  • 56. What is Gradle? • Tool to assist automating (build) steps task hello << { println 'Hello world!' } task intro(dependsOn: hello) << { © ASERT 2008-2010 println "I'm Gradle" } > gradle -q intro Hello world! I'm Gradle ESDC 2010 - 56
  • 57. 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 © ASERT 2006-2010 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 - 57
  • 58. Gradle Examples © ASERT 2006-2010 ESDC 2010 - 58
  • 59. Revisiting our Preview Example Switching to IDE © ASERT 2008-2010 ESDC 2010 - 59
  • 60. Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle Other Tools • More Info ESDC 2010 - 60
  • 61. 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 © ASERT 2006-2010 • Hudson CLI and GroovyShell Source: http://weblogs.java.net/blog/kohsuke/archive/2009/05/hudson_cli_and.html ESDC 2010 - 61
  • 62. 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() } © ASERT 2006-2010 Source: http://wiki.hudson-ci.org/display/HUDSON/Groovy+Postbuild+Plugin
  • 63. ...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) © ASERT 2006-2010 } appendText("</ul>", false) } } Adapted from: http://wiki.hudson-ci.org/display/HUDSON/Groovy+Postbuild+Plugin
  • 64. Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle • Other Tools More Info ESDC 2010 - 64
  • 65. More Information... • 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 © ASERT 2008-2010 – http://gant.codehaus.org/ • Maven – http://maven.apache.org – http://gmaven.codehaus.org • Gradle – http://gradle.org ESDC 2010 - 65
  • 66. ...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 – user@groovy.codehaus.org © ASERT 2006-2010 • 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 ESDC 2010 - 66
  • 67. GinA 2ed “ReGinA” is coming ... © ASERT 2006-2010