SlideShare uma empresa Scribd logo
1 de 68
Baixar para ler 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: Maven 3 Groovy Dialect
                    project {
                      modelVersion '4.0.0'
                      groupId 'org.groovycookbook.builds'
                      artifactId 'stringutils'
                      packaging 'jar'
                      version '1.0-SNAPSHOT'
                      name 'stringutils'
                      url 'http://maven.apache.org'
                      dependencies {
                        dependency 'junit:junit:4.7:test'
© ASERT 2008-2010




                      }
                      build {
                        plugins {
                          /* this is a java 1.5 project */
                          plugin {
                            groupId 'org.apache.maven.plugins'
                            artifactId 'maven-compiler-plugin'
                            configuration {
                              source '1.5'
                              target '1.5'
                            }
                          }
                        }
                      }
                    }                                            ESDC 2010 - 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 - 16
Topics
                    • Build Pain Points
                    • Build Tool Landscape
                    Groovy Intro
                    • Ant & friends
                    • Maven & friends
© ASERT 2008-2010




                    • Gradle
                    • Other Tools
                    • More Info



                                               ESDC 2010 - 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 - 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 - 19
Growing Acceptance …
  A slow and steady start but now gaining in
  momentum, maturity and mindshare




Now free
… Growing Acceptance …
© ASERT 2008-2010




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




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




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




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




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




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




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




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




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




                                           ESDC 2010 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 49
What is Maven?
                    • Tool to assist automating (build) steps
© ASERT 2008-2010




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




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




                    Gradle
                    • Other Tools
                    • More Info



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




                                      ESDC 2010 - 59
Revisiting our Preview Example

                                               Switching
                                               to IDE
© ASERT 2008-2010




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




                    • Gradle
                    Other Tools
                    • More Info



                                               ESDC 2010 - 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 - 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
...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 - 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 - 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 - 67
GinA 2ed “ReGinA” is coming ...
© ASERT 2006-2010

Mais conteúdo relacionado

Destaque

concurrency gpars
concurrency gparsconcurrency gpars
concurrency gparsPaul King
 
Java Build Tools
Java Build ToolsJava Build Tools
Java Build Tools­Avishek A
 
Ant_quick_guide
Ant_quick_guideAnt_quick_guide
Ant_quick_guideducquoc_vn
 
Zen and-the-art-of-build-script-maintenance-skillsmatter
Zen and-the-art-of-build-script-maintenance-skillsmatterZen and-the-art-of-build-script-maintenance-skillsmatter
Zen and-the-art-of-build-script-maintenance-skillsmatterSkills Matter
 
Architecting your Frontend
Architecting your FrontendArchitecting your Frontend
Architecting your FrontendRuben Teijeiro
 
Angular.js
Angular.jsAngular.js
Angular.jsGDG Cali
 
Gradle 2.Write once, builde everywhere
Gradle 2.Write once, builde everywhereGradle 2.Write once, builde everywhere
Gradle 2.Write once, builde everywhereStrannik_2013
 
4장. Class Loader
4장. Class Loader4장. Class Loader
4장. Class Loader김 한도
 
Tutorial to develop build files using ANT
Tutorial to develop build files using ANTTutorial to develop build files using ANT
Tutorial to develop build files using ANTravireddy76
 
Apache ant
Apache antApache ant
Apache antkoniik
 
Java Build Tool course in 2011
Java Build Tool course in 2011Java Build Tool course in 2011
Java Build Tool course in 2011Ching Yi Chan
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend TestingNeil Crosby
 
Front-End Testing: Demystified
Front-End Testing: DemystifiedFront-End Testing: Demystified
Front-End Testing: DemystifiedSeth McLaughlin
 
Erlang vs. Java
Erlang vs. JavaErlang vs. Java
Erlang vs. JavaArtan Cami
 

Destaque (20)

concurrency gpars
concurrency gparsconcurrency gpars
concurrency gpars
 
Jvm a brief introduction
Jvm  a brief introductionJvm  a brief introduction
Jvm a brief introduction
 
Java Build Tools
Java Build ToolsJava Build Tools
Java Build Tools
 
Ant_quick_guide
Ant_quick_guideAnt_quick_guide
Ant_quick_guide
 
Zen and-the-art-of-build-script-maintenance-skillsmatter
Zen and-the-art-of-build-script-maintenance-skillsmatterZen and-the-art-of-build-script-maintenance-skillsmatter
Zen and-the-art-of-build-script-maintenance-skillsmatter
 
Architecting your Frontend
Architecting your FrontendArchitecting your Frontend
Architecting your Frontend
 
Angular.js
Angular.jsAngular.js
Angular.js
 
Gradle 2.Write once, builde everywhere
Gradle 2.Write once, builde everywhereGradle 2.Write once, builde everywhere
Gradle 2.Write once, builde everywhere
 
Apache maven 2 overview
Apache maven 2 overviewApache maven 2 overview
Apache maven 2 overview
 
4장. Class Loader
4장. Class Loader4장. Class Loader
4장. Class Loader
 
Tutorial to develop build files using ANT
Tutorial to develop build files using ANTTutorial to develop build files using ANT
Tutorial to develop build files using ANT
 
Apache maven 2 overview
Apache maven 2 overviewApache maven 2 overview
Apache maven 2 overview
 
Apache ant
Apache antApache ant
Apache ant
 
Java Classloaders
Java ClassloadersJava Classloaders
Java Classloaders
 
Java Build Tool course in 2011
Java Build Tool course in 2011Java Build Tool course in 2011
Java Build Tool course in 2011
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend Testing
 
Apache Ant
Apache AntApache Ant
Apache Ant
 
Front-End Testing: Demystified
Front-End Testing: DemystifiedFront-End Testing: Demystified
Front-End Testing: Demystified
 
Apache Ant
Apache AntApache Ant
Apache Ant
 
Erlang vs. Java
Erlang vs. JavaErlang vs. Java
Erlang vs. Java
 

Semelhante a Make Your Builds More 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
 
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
 
Tech Ed09 India Ver M New
Tech Ed09 India Ver M NewTech Ed09 India Ver M New
Tech Ed09 India Ver M Newrsnarayanan
 
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
 

Semelhante a Make Your Builds More 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
 
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
 
Tech Ed09 India Ver M New
Tech Ed09 India Ver M NewTech Ed09 India Ver M New
Tech Ed09 India Ver M New
 
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
 

Mais de Paul King

awesome groovy
awesome groovyawesome groovy
awesome groovyPaul King
 
groovy databases
groovy databasesgroovy databases
groovy databasesPaul King
 
groovy transforms
groovy transformsgroovy transforms
groovy transformsPaul King
 
tictactoe groovy
tictactoe groovytictactoe groovy
tictactoe groovyPaul King
 
groovy rules
groovy rulesgroovy rules
groovy rulesPaul King
 
functional groovy
functional groovyfunctional groovy
functional groovyPaul King
 
Make Testing Groovy
Make Testing GroovyMake Testing Groovy
Make Testing GroovyPaul King
 
groovy DSLs from beginner to expert
groovy DSLs from beginner to expertgroovy DSLs from beginner to expert
groovy DSLs from beginner to expertPaul King
 
concurrency with GPars
concurrency with GParsconcurrency with GPars
concurrency with GParsPaul King
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy PluginsPaul King
 
Groovy Power Features
Groovy Power FeaturesGroovy Power Features
Groovy Power FeaturesPaul King
 
Make Your Testing Groovy
Make Your Testing GroovyMake Your Testing Groovy
Make Your Testing GroovyPaul King
 
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...
Craig Smith & Paul King   Agile Tool Hacking   Taking Your Agile Development ...Craig Smith & Paul King   Agile Tool Hacking   Taking Your Agile Development ...
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...Paul King
 
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Paul King
 
XML and Web Services with Groovy
XML and Web Services with GroovyXML and Web Services with Groovy
XML and Web Services with GroovyPaul King
 

Mais de Paul King (15)

awesome groovy
awesome groovyawesome groovy
awesome groovy
 
groovy databases
groovy databasesgroovy databases
groovy databases
 
groovy transforms
groovy transformsgroovy transforms
groovy transforms
 
tictactoe groovy
tictactoe groovytictactoe groovy
tictactoe groovy
 
groovy rules
groovy rulesgroovy rules
groovy rules
 
functional groovy
functional groovyfunctional groovy
functional groovy
 
Make Testing Groovy
Make Testing GroovyMake Testing Groovy
Make Testing Groovy
 
groovy DSLs from beginner to expert
groovy DSLs from beginner to expertgroovy DSLs from beginner to expert
groovy DSLs from beginner to expert
 
concurrency with GPars
concurrency with GParsconcurrency with GPars
concurrency with GPars
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy Plugins
 
Groovy Power Features
Groovy Power FeaturesGroovy Power Features
Groovy Power Features
 
Make Your Testing Groovy
Make Your Testing GroovyMake Your Testing Groovy
Make Your Testing Groovy
 
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...
Craig Smith & Paul King   Agile Tool Hacking   Taking Your Agile Development ...Craig Smith & Paul King   Agile Tool Hacking   Taking Your Agile Development ...
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...
 
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
 
XML and Web Services with Groovy
XML and Web Services with GroovyXML and Web Services with Groovy
XML and Web Services with Groovy
 

Último

Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 

Último (20)

Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 

Make Your Builds More 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: Maven 3 Groovy Dialect project { modelVersion '4.0.0' groupId 'org.groovycookbook.builds' artifactId 'stringutils' packaging 'jar' version '1.0-SNAPSHOT' name 'stringutils' url 'http://maven.apache.org' dependencies { dependency 'junit:junit:4.7:test' © ASERT 2008-2010 } build { plugins { /* this is a java 1.5 project */ plugin { groupId 'org.apache.maven.plugins' artifactId 'maven-compiler-plugin' configuration { source '1.5' target '1.5' } } } } } ESDC 2010 - 15
  • 16. ...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 - 16
  • 17. Topics • Build Pain Points • Build Tool Landscape Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle • Other Tools • More Info ESDC 2010 - 17
  • 18. 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 - 18
  • 19. 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 - 19
  • 20. Growing Acceptance … A slow and steady start but now gaining in momentum, maturity and mindshare Now free
  • 21. … Growing Acceptance … © ASERT 2008-2010 ESDC 2010 - 21
  • 22. … Growing Acceptance … © ASERT 2008-2010 Groovy and Grails downloads: 70-90K per month and growing ESDC 2010 - 22
  • 23. … Growing Acceptance … © ASERT 2008-2010 Source: http://www.micropoll.com/akira/mpresult/501697-116746 Source: http://www.grailspodcast.co ESDC 2010 - 23
  • 24. … Growing Acceptance … © ASERT 2008-2010 http://www.jroller.com/scolebourne/entry/devoxx_2008_whitebo http://www.java.net ESDC 2010 - 24
  • 25. … Growing Acceptance © ASERT 2006-2010 http://pollpigeon.com/jsf-grails-wicket/r/25665/ ESDC 2010 - 25
  • 26. … Growing Acceptance … What alternative JVM language are you using or intending to use © ASERT 2008-2010 http://www.leonardoborges.com/writings ESDC 2010 - 26
  • 27. … Growing Acceptance … © ASERT 2008-2010 http://it-republik.de/jaxenter/quickvote/results/1/poll/44 (translated using http://babelfish.yahoo ESDC 2010 - 27
  • 28. … Growing Acceptance © ASERT 2008-2010 ESDC 2010 - 28
  • 29. 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 - 29
  • 30. 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 - 30
  • 31. 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 - 31
  • 32. ...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 - 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) } } 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 - 33
  • 34. ...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 - 34
  • 35. ...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 - 35
  • 36. ...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 - 36
  • 37. ...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 - 37
  • 38. ...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 - 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 ESDC 2010 - 39
  • 40. ...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 - 40
  • 41. 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 - 41
  • 42. 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 - 42
  • 43. 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 - 43
  • 44. 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 - 44
  • 45. 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 - 45
  • 46. ...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 - 46
  • 47. 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 - 47
  • 48. 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 - 48
  • 49. 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 - 49
  • 50. What is Maven? • Tool to assist automating (build) steps © ASERT 2008-2010 ESDC 2010 - 50
  • 51. 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 - 51
  • 52. ...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 - 52
  • 53. ...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 - 53
  • 54. ...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 - 54
  • 55. ...Builds: GMaven © ASERT 2006-2010 ESDC 2010 - 55
  • 56. Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 Gradle • Other Tools • More Info ESDC 2010 - 56
  • 57. 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 - 57
  • 58. 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 - 58
  • 59. Gradle Examples © ASERT 2006-2010 ESDC 2010 - 59
  • 60. Revisiting our Preview Example Switching to IDE © ASERT 2008-2010 ESDC 2010 - 60
  • 61. Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle Other Tools • More Info ESDC 2010 - 61
  • 62. 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 - 62
  • 63. 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
  • 64. ...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
  • 65. Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle • Other Tools More Info ESDC 2010 - 65
  • 66. 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 - 66
  • 67. ...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 - 67
  • 68. GinA 2ed “ReGinA” is coming ... © ASERT 2006-2010