A Tour Through the Groovy Ecosystem
                                     at




                                       Examples available on Github
                           https://github.com/xlson/presentations/tree/master/
                                     groovy-ecosystem-dyncon_2011




Saturday, March 12, 2011
Leonard Axelsson
                • Groovy developer since 2007
                • Co-Founder of SweGUG
                      –Swedish Groovy User Group
                • Speaker at Javaforum,
                  GTUG, Agical Geeknight,
                  JFokus, SweGUG                   @xlson
                • Developer/Consultant at          http://xlson.com/
                  Agical


Saturday, March 12, 2011
a long long time ago
                          (4 years or so ;)




Saturday, March 12, 2011
Overview
                • Part 1: Groovy intro ~15 mins

                     • Short and sweet

                • Part 2: Ecosystem ~20 mins

                     • Mapping the wilderness

                • Part 3: Questions?!?!? :)


Saturday, March 12, 2011
Groovy Overview

                • Originated in 2003

                • Under the Apache License

                • Runs on the Java Virtual Machine

                • Grammar derived from Java 1.5




Saturday, March 12, 2011
Groovy Overview
                • Dynamic language

                     • Inspired by Python, Ruby and Smalltalk

                • Object Oriented

                • Easy to learn for Java devs

                     • Supports Java style code out of the box

                • Scriptable

                • Embeddable



Saturday, March 12, 2011
Dynamic Language
                • No compile-time checking

                     • int i = “Hello”                   throws exception at runtime

                • Ducktyping

                     • def     keyword allows you to care about what
                           the object does, not what it is

                • Supports custom DSLs
            new DateDSL().last.day.in.december( 2009 )

                             http://groovyconsole.appspot.com/view.groovy?id=27001

Saturday, March 12, 2011
The obligatory Hello
                                 World




Saturday, March 12, 2011
How many in here
                            know Groovy?




Saturday, March 12, 2011
Ok, so how many in here know
                 some Java?




Saturday, March 12, 2011
HelloWorld.java
        class HelloWorld {
            public static void main(String[] args) {
                System.out.println("Hello World!");
            }
        }




Saturday, March 12, 2011
HelloWorld.groovy
        class HelloWorld {
            public static void main(String[] args) {
                System.out.println("Hello World!");
            }
        }




Saturday, March 12, 2011
Removing ...
        class HelloWorld {
            public static void main(String[] args) {
                System.out.println("Hello World!");
            }
        }




Saturday, March 12, 2011
Removing ...
        class HelloWorld {
            public static void main(String[] args) {
                System.out.println("Hello World!")
            }
        }




Saturday, March 12, 2011
Removing ...
        class HelloWorld {
            public static void main(String[] args) {
                println("Hello World!")
            }
        }




Saturday, March 12, 2011
Removing ...
        println("Hello World!")




Saturday, March 12, 2011
This is it
        println "Hello World!"




Saturday, March 12, 2011
Feature Overview
                • Properties

                     • dynamic getters and setters

                • Closures

                     • reusable blocks of code

                • Meta Object Protocol

                     • rewrite behaviour at runtime

                • Many additions to the JDK



Saturday, March 12, 2011
Primitives are objects
                                 to
                int a = 5        // Normal string
                long b = 1       String message = 'got $5?'
                float f = 5.4
                double d = 5.4   // Double quoted string supports macros
                                 String longerMessage = "Have you $message"

                                 // Multiline strings available as well
                                 String email = """Hi!
                                 How are you?

                                 /Leo"""

                                 println message
                                 println longerMessage
                                 println email




Saturday, March 12, 2011
Plain Old Groovy
                                Objects




Saturday, March 12, 2011
POGO’s
                • Properties

                     • getters and setters are created
                       automatically




Saturday, March 12, 2011
POGO’s
                • Properties

                     • getters and setters are created
                       automatically

                • Named Parameters

                     • clarifies intent



Saturday, March 12, 2011
POGO’s

        class Person {
            String name
            String lastname
        }

        def anders = new Person(name: 'Anders', lastname: 'Andersson')
        assert anders.getName() == 'Anders'

        // Anders gets married and changes his lastname
        anders.setLastname("Sundstedt")
        assert anders.lastname == "Sundstedt"




Saturday, March 12, 2011
POGO’s
                • Getters and setters can be overridden
        class Person {
            def name
            def lastname

               String setLastname(String lastname) {
                   this.lastname = lastname.reverse()
               }
        }

        def anders = new Person(name: 'Anders', lastname: 'Andersson')

        // Anders does a strange change of his lastname
        anders.lastname = "Sundstedt"
        assert anders.lastname == "tdetsdnuS"




Saturday, March 12, 2011
Built in syntax for lists
                           and maps


Saturday, March 12, 2011
Lists
   List syntax:
         def names = ['Leonard', 'Anna', 'Anders']
         assert names instanceof List
         assert names.size() == 3
         assert names[0] == 'Leonard'




Saturday, March 12, 2011
Maps
        def map = [name: 'Leonard',
                   lastname: 'Axelsson']
        assert map.name == 'Leonard'
        assert map['lastname'] == 'Axelsson'

        map.each{ key, value ->
            println "Key: $key, Value: $value"
        }




    Output:
        Key: name, Value: Leonard
        Key: lastname, Value: Axelsson




Saturday, March 12, 2011
each, find and findAll
        class Person {
            String name
            String lastname
            boolean male
        }

        def ages = [new Person(name: 'Bo', lastname: 'Olsson', male: true),
                    new Person(name: 'Gunn', lastname: 'Bertilsson', male: false),
                    new Person(name: 'Britt', lastname: 'Olsson', male: false)]
        // Print all names
        ages.each { println "$it.name $it.lastname" }

        // Find one male
        assert ages.find{ person -> person.male }.name == 'Bo'

        // or find all females
        assert ages.findAll{ Person p -> !p.male }.size() == 2




Saturday, March 12, 2011
Putting the basics
                                together

                   (0..7).collect{(('a'..'z')+('A'..'Z')+(0..9))[new Random().nextInt(62)]}.join()




Saturday, March 12, 2011
AST Transformations
                           Compile-time meta programming




Saturday, March 12, 2011
@Log

                import groovy.util.logging.*

                @Log
                class LogDemo {

                       def usesLogger() {
                           log.info "Uses the log annotation."
                       }

                       static void main(String[] args) {
                           new LogDemo().usesLogger()
                       }
                }




Saturday, March 12, 2011
@Immutable
                import groovy.transform.*

                @Immutable
                class User {
                    String name
                    String lastname
                }

                def user = new User(name: 'Leo', lastname: 'Axelsson')

                try {
                    user.name = 'Anders'
                } catch(ReadOnlyPropertyException e) {
                    println("Changing a property of an Immutable object will not work.")
                }



                println user




Saturday, March 12, 2011
@EqualsAndHashCode

                import groovy.transform.*

                @EqualsAndHashCode
                class User {
                    String name
                    String lastname
                }

                def user1 = new User(name: 'Leo', lastname: 'Axelsson')
                def user2 = new User(name: 'Leo', lastname: 'Axelsson')

                assert user1 == user2




Saturday, March 12, 2011
Mapping the
                                   ecosystem
                           So, we’ve already started, but let’s do some more
                                            sightseeing...




Saturday, March 12, 2011
GPars
                • Parallelization framework

                • Features

                     • Actors

                     • Agents

                     • Dataflow

                     • Parallell Collection Processing


Saturday, March 12, 2011
GPars
        @Grab(group='org.codehaus.gpars', module='gpars', version='0.10')
        import groovyx.gpars.GParsExecutorsPool

        def importProcessingData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 ,18, 19, 20]

        time('Parallel execution') {
            GParsExecutorsPool.withPool {
                importProcessingData.eachParallel { data ->
                    // Insert arbitrary heavy operation here
                    sleep 200
                }

             }
        }

        time('Linear execution') {
            importProcessingData.each {
                // Insert arbitrary heavy operation here
                sleep 200
            }
        }

        def time(String desc, task) {
            def startTime = new Date().time
            def result = task()
            def executionTime = new Date().time - startTime
            println "$desc took: $executionTime ms."
            result
        }



Saturday, March 12, 2011
GPars
                • Output (executed on dual-core machine):
                 Parallel execution took: 1449 ms.
                 Linear execution took: 4006 ms.




Saturday, March 12, 2011
@Grab and grape
                • Dependency management using Apache Ivy

                     • Uses Maven Central

                • grape

                     • Commandline tool to manage dependencies

                • @Grab annotation

                     • Provides dependcies in scripts


Saturday, March 12, 2011
Web




Saturday, March 12, 2011
Grails
                • Convention Over Configuration

                • Used on one of Great Britains biggest(?)
                  public sites: Sky.com

                • Stands upon the shoulders of giants

                • Rich plugin system



Saturday, March 12, 2011
Grails
                                                 -14 :20
                • Convention Over Configuration
                                            13  :40
                                     ow at
                                  orr      ! :)
                              tom rrien biggest(?)
         • Used on one of Great Britains s
                         ails k Ju
           public sites:r Sky.com
                ou tG         en
             ab with H
        ore
       M • Stands upon the shoulders of giants
                • Rich plugin system



Saturday, March 12, 2011
Testing,
                 what to say about testing...
                • Spock

                • EasyB

                • GroovyTestCase

                • MockFor()

                • Expandos and Maps

                • Geb

                • SoapUI

                • Groovy Remote Control




Saturday, March 12, 2011
Spock


                • Great testing framework

                • Easy to read (and write)




Saturday, March 12, 2011
Spock:
                                  Readable tests
                @Grab('org.spockframework:spock-core:0.5-groovy-1.8')
                @GrabExclude('org.codehaus.groovy:groovy-all:1.8.0-beta-3')
                import spock.lang.*

                class ReadableSpec extends Specification {

                       def "All is well in math-land"() {
                           expect:
                           sum == a + b

                           where:
                           a   | b | sum
                           1   | 5 | 6
                           6   | 2 | 8
                       }
                }




Saturday, March 12, 2011
Spock:
                                Unroll your tests
                @Grab('org.spockframework:spock-core:0.5-groovy-1.8')
                @GrabExclude('org.codehaus.groovy:groovy-all:1.8.0-beta-3')
                import spock.lang.*

                class UnrolledSpec extends Specification {

                       @Unroll({"The sum of $a and $b should be $sum."})
                       def "All is well in math-land"() {
                           expect:
                           sum == a + b

                           where:
                           a   | b   |   sum
                           1   | 5   |   6
                           6   | 2   |   8
                           10 | 2    |   11
                       }
                }




Saturday, March 12, 2011
Geb
                • Wanna surf programmatically?

                     • Geb == really nice and easy browser
                       automation

                • jQuery style for navigation API

                     • even supports calling out to jQuery

                • Page objects


Saturday, March 12, 2011
Geb:
                           Headless Browsing

                @Grab('org.codehaus.geb:geb-core:0.5.1')
                @Grab('org.seleniumhq.selenium:selenium-htmlunit-driver:2.0a7')
                import geb.Browser

                Browser.drive("http://xlson.com/") {
                    assert title == "Leonard Axelsson"
                }




Saturday, March 12, 2011
Geb:
                Finding Dyncon using Firefox
                @Grab('org.codehaus.geb:geb-core:0.5.1')
                @Grab('org.seleniumhq.selenium:selenium-firefox-driver:2.0a7')
                import geb.Browser

                Browser.drive("http://google.se/") {
                    assert title == 'Google'
                    $("input", name: "q").value("Dyncon 2011")
                    $("input", name: "btnG").click()

                       waitFor { title.startsWith("Dyncon 2011") }

                       def firstLink = $("li.g", 0).find("a.l")
                       assert firstLink.text() == "Dyncon 2011"
                       firstLink.click()
                }




Saturday, March 12, 2011
Building




Saturday, March 12, 2011
AntBuilder

                • Gives you the power of Ant in Groovy

                • ..the power of what?

                     • Well, platform independent file handling
                       among other things




Saturday, March 12, 2011
AntBuilder
                def ant = new AntBuilder()

                // lets just call one task
                ant.echo("hello")

                // here is an example of a block of Ant inside GroovyMarkup
                ant.sequential {
                    echo("inside sequential")
                    myDir = "target/AntTest/"
                    mkdir(dir:myDir)
                    copy(todir:myDir) {
                        fileset(dir:"src/test") {
                            include(name:"**/*.groovy")
                        }
                    }
                    echo("done")
                }

                // now lets do some normal Groovy again
                file = new File("target/AntTest/groovy/util/AntTest.groovy")
                assert file.exists()




Saturday, March 12, 2011
Gradle
                • Easy to get started with

                     • Bye bye ‘copy-paste’-pattern

                • Declarative OR Build by Convention

                • Extremely Extendable

                • Integrates with Ivy for dependency
                  management


Saturday, March 12, 2011
Gradle:
                                 Highlights
                • Easy for the first 80% of functionality

                     • ...easy for the 20% last as well

                • Keeps track of what’s changed

                • Works everywhere thanks to the Gradle
                  Wrapper




Saturday, March 12, 2011
Gradle:
                               Simply Groovy
                apply plugin: 'groovy'
                apply plugin: 'application'

                repositories {
                    mavenCentral()
                }

                dependencies {
                    groovy 'org.codehaus.groovy:groovy-all:1.7.9'
                }

                mainClassName='HelloWorld'




Saturday, March 12, 2011
Gradle:
                            Multiproject


                • Head out to the code... :)




Saturday, March 12, 2011
Other goodies




Saturday, March 12, 2011
Griffon

                • Grails for the desktop

                • Early days but lots of plugins

                • DSL for Swing

                     • Extends SwingBuilder




Saturday, March 12, 2011
GroovyServ


                     • Speeds up execution of Groovy scripts

                     • Groovy for small utils finally valid!




Saturday, March 12, 2011
GroovyServ:
                 Pretty XML on the commandline

                #!/usr/bin/env groovyclient

                println(prettyPrintXml(System.in.text))

                def prettyPrintXml(text) {
                    def xmlNode = new XmlParser().parseText(text)
                    def writer = new StringWriter()
                    def printer = new XmlNodePrinter(new PrintWriter(writer))
                    printer.preserveWhitespace = true
                    printer.print(xmlNode)
                    writer.toString().trim()
                }




Saturday, March 12, 2011
Links
                •    Groovy

                     •     http://groovy.codehaus.org/

                •    Groovy Goodness (great tips and trix)

                     •     http://mrhaki.blogspot.com/

                •    Groovy Web Console (on Appengine)

                     •     http://groovyconsole.appspot.com/

                •    My blog

                     •     http://xlson.com/

                •    SweGUG

                     •     http://groups.google.com/group/swegug




Saturday, March 12, 2011

A Tour Through the Groovy Ecosystem

  • 1.
    A Tour Throughthe Groovy Ecosystem at Examples available on Github https://github.com/xlson/presentations/tree/master/ groovy-ecosystem-dyncon_2011 Saturday, March 12, 2011
  • 2.
    Leonard Axelsson • Groovy developer since 2007 • Co-Founder of SweGUG –Swedish Groovy User Group • Speaker at Javaforum, GTUG, Agical Geeknight, JFokus, SweGUG @xlson • Developer/Consultant at http://xlson.com/ Agical Saturday, March 12, 2011
  • 3.
    a long longtime ago (4 years or so ;) Saturday, March 12, 2011
  • 4.
    Overview • Part 1: Groovy intro ~15 mins • Short and sweet • Part 2: Ecosystem ~20 mins • Mapping the wilderness • Part 3: Questions?!?!? :) Saturday, March 12, 2011
  • 5.
    Groovy Overview • Originated in 2003 • Under the Apache License • Runs on the Java Virtual Machine • Grammar derived from Java 1.5 Saturday, March 12, 2011
  • 6.
    Groovy Overview • Dynamic language • Inspired by Python, Ruby and Smalltalk • Object Oriented • Easy to learn for Java devs • Supports Java style code out of the box • Scriptable • Embeddable Saturday, March 12, 2011
  • 7.
    Dynamic Language • No compile-time checking • int i = “Hello” throws exception at runtime • Ducktyping • def keyword allows you to care about what the object does, not what it is • Supports custom DSLs new DateDSL().last.day.in.december( 2009 ) http://groovyconsole.appspot.com/view.groovy?id=27001 Saturday, March 12, 2011
  • 8.
    The obligatory Hello World Saturday, March 12, 2011
  • 9.
    How many inhere know Groovy? Saturday, March 12, 2011
  • 10.
    Ok, so howmany in here know some Java? Saturday, March 12, 2011
  • 11.
    HelloWorld.java class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } Saturday, March 12, 2011
  • 12.
    HelloWorld.groovy class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } Saturday, March 12, 2011
  • 13.
    Removing ... class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } Saturday, March 12, 2011
  • 14.
    Removing ... class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!") } } Saturday, March 12, 2011
  • 15.
    Removing ... class HelloWorld { public static void main(String[] args) { println("Hello World!") } } Saturday, March 12, 2011
  • 16.
    Removing ... println("Hello World!") Saturday, March 12, 2011
  • 17.
    This is it println "Hello World!" Saturday, March 12, 2011
  • 18.
    Feature Overview • Properties • dynamic getters and setters • Closures • reusable blocks of code • Meta Object Protocol • rewrite behaviour at runtime • Many additions to the JDK Saturday, March 12, 2011
  • 19.
    Primitives are objects to int a = 5 // Normal string long b = 1 String message = 'got $5?' float f = 5.4 double d = 5.4 // Double quoted string supports macros String longerMessage = "Have you $message" // Multiline strings available as well String email = """Hi! How are you? /Leo""" println message println longerMessage println email Saturday, March 12, 2011
  • 20.
    Plain Old Groovy Objects Saturday, March 12, 2011
  • 21.
    POGO’s • Properties • getters and setters are created automatically Saturday, March 12, 2011
  • 22.
    POGO’s • Properties • getters and setters are created automatically • Named Parameters • clarifies intent Saturday, March 12, 2011
  • 23.
    POGO’s class Person { String name String lastname } def anders = new Person(name: 'Anders', lastname: 'Andersson') assert anders.getName() == 'Anders' // Anders gets married and changes his lastname anders.setLastname("Sundstedt") assert anders.lastname == "Sundstedt" Saturday, March 12, 2011
  • 24.
    POGO’s • Getters and setters can be overridden class Person { def name def lastname String setLastname(String lastname) { this.lastname = lastname.reverse() } } def anders = new Person(name: 'Anders', lastname: 'Andersson') // Anders does a strange change of his lastname anders.lastname = "Sundstedt" assert anders.lastname == "tdetsdnuS" Saturday, March 12, 2011
  • 25.
    Built in syntaxfor lists and maps Saturday, March 12, 2011
  • 26.
    Lists List syntax: def names = ['Leonard', 'Anna', 'Anders'] assert names instanceof List assert names.size() == 3 assert names[0] == 'Leonard' Saturday, March 12, 2011
  • 27.
    Maps def map = [name: 'Leonard', lastname: 'Axelsson'] assert map.name == 'Leonard' assert map['lastname'] == 'Axelsson' map.each{ key, value -> println "Key: $key, Value: $value" } Output: Key: name, Value: Leonard Key: lastname, Value: Axelsson Saturday, March 12, 2011
  • 28.
    each, find andfindAll class Person { String name String lastname boolean male } def ages = [new Person(name: 'Bo', lastname: 'Olsson', male: true), new Person(name: 'Gunn', lastname: 'Bertilsson', male: false), new Person(name: 'Britt', lastname: 'Olsson', male: false)] // Print all names ages.each { println "$it.name $it.lastname" } // Find one male assert ages.find{ person -> person.male }.name == 'Bo' // or find all females assert ages.findAll{ Person p -> !p.male }.size() == 2 Saturday, March 12, 2011
  • 29.
    Putting the basics together (0..7).collect{(('a'..'z')+('A'..'Z')+(0..9))[new Random().nextInt(62)]}.join() Saturday, March 12, 2011
  • 30.
    AST Transformations Compile-time meta programming Saturday, March 12, 2011
  • 31.
    @Log import groovy.util.logging.* @Log class LogDemo { def usesLogger() { log.info "Uses the log annotation." } static void main(String[] args) { new LogDemo().usesLogger() } } Saturday, March 12, 2011
  • 32.
    @Immutable import groovy.transform.* @Immutable class User { String name String lastname } def user = new User(name: 'Leo', lastname: 'Axelsson') try { user.name = 'Anders' } catch(ReadOnlyPropertyException e) { println("Changing a property of an Immutable object will not work.") } println user Saturday, March 12, 2011
  • 33.
    @EqualsAndHashCode import groovy.transform.* @EqualsAndHashCode class User { String name String lastname } def user1 = new User(name: 'Leo', lastname: 'Axelsson') def user2 = new User(name: 'Leo', lastname: 'Axelsson') assert user1 == user2 Saturday, March 12, 2011
  • 34.
    Mapping the ecosystem So, we’ve already started, but let’s do some more sightseeing... Saturday, March 12, 2011
  • 35.
    GPars • Parallelization framework • Features • Actors • Agents • Dataflow • Parallell Collection Processing Saturday, March 12, 2011
  • 36.
    GPars @Grab(group='org.codehaus.gpars', module='gpars', version='0.10') import groovyx.gpars.GParsExecutorsPool def importProcessingData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 ,18, 19, 20] time('Parallel execution') { GParsExecutorsPool.withPool { importProcessingData.eachParallel { data -> // Insert arbitrary heavy operation here sleep 200 } } } time('Linear execution') { importProcessingData.each { // Insert arbitrary heavy operation here sleep 200 } } def time(String desc, task) { def startTime = new Date().time def result = task() def executionTime = new Date().time - startTime println "$desc took: $executionTime ms." result } Saturday, March 12, 2011
  • 37.
    GPars • Output (executed on dual-core machine): Parallel execution took: 1449 ms. Linear execution took: 4006 ms. Saturday, March 12, 2011
  • 38.
    @Grab and grape • Dependency management using Apache Ivy • Uses Maven Central • grape • Commandline tool to manage dependencies • @Grab annotation • Provides dependcies in scripts Saturday, March 12, 2011
  • 39.
  • 40.
    Grails • Convention Over Configuration • Used on one of Great Britains biggest(?) public sites: Sky.com • Stands upon the shoulders of giants • Rich plugin system Saturday, March 12, 2011
  • 41.
    Grails -14 :20 • Convention Over Configuration 13 :40 ow at orr ! :) tom rrien biggest(?) • Used on one of Great Britains s ails k Ju public sites:r Sky.com ou tG en ab with H ore M • Stands upon the shoulders of giants • Rich plugin system Saturday, March 12, 2011
  • 42.
    Testing, what to say about testing... • Spock • EasyB • GroovyTestCase • MockFor() • Expandos and Maps • Geb • SoapUI • Groovy Remote Control Saturday, March 12, 2011
  • 43.
    Spock • Great testing framework • Easy to read (and write) Saturday, March 12, 2011
  • 44.
    Spock: Readable tests @Grab('org.spockframework:spock-core:0.5-groovy-1.8') @GrabExclude('org.codehaus.groovy:groovy-all:1.8.0-beta-3') import spock.lang.* class ReadableSpec extends Specification { def "All is well in math-land"() { expect: sum == a + b where: a | b | sum 1 | 5 | 6 6 | 2 | 8 } } Saturday, March 12, 2011
  • 45.
    Spock: Unroll your tests @Grab('org.spockframework:spock-core:0.5-groovy-1.8') @GrabExclude('org.codehaus.groovy:groovy-all:1.8.0-beta-3') import spock.lang.* class UnrolledSpec extends Specification { @Unroll({"The sum of $a and $b should be $sum."}) def "All is well in math-land"() { expect: sum == a + b where: a | b | sum 1 | 5 | 6 6 | 2 | 8 10 | 2 | 11 } } Saturday, March 12, 2011
  • 46.
    Geb • Wanna surf programmatically? • Geb == really nice and easy browser automation • jQuery style for navigation API • even supports calling out to jQuery • Page objects Saturday, March 12, 2011
  • 47.
    Geb: Headless Browsing @Grab('org.codehaus.geb:geb-core:0.5.1') @Grab('org.seleniumhq.selenium:selenium-htmlunit-driver:2.0a7') import geb.Browser Browser.drive("http://xlson.com/") { assert title == "Leonard Axelsson" } Saturday, March 12, 2011
  • 48.
    Geb: Finding Dyncon using Firefox @Grab('org.codehaus.geb:geb-core:0.5.1') @Grab('org.seleniumhq.selenium:selenium-firefox-driver:2.0a7') import geb.Browser Browser.drive("http://google.se/") { assert title == 'Google' $("input", name: "q").value("Dyncon 2011") $("input", name: "btnG").click() waitFor { title.startsWith("Dyncon 2011") } def firstLink = $("li.g", 0).find("a.l") assert firstLink.text() == "Dyncon 2011" firstLink.click() } Saturday, March 12, 2011
  • 49.
  • 50.
    AntBuilder • Gives you the power of Ant in Groovy • ..the power of what? • Well, platform independent file handling among other things Saturday, March 12, 2011
  • 51.
    AntBuilder def ant = new AntBuilder() // lets just call one task ant.echo("hello") // here is an example of a block of Ant inside GroovyMarkup ant.sequential { echo("inside sequential") myDir = "target/AntTest/" mkdir(dir:myDir) copy(todir:myDir) { fileset(dir:"src/test") { include(name:"**/*.groovy") } } echo("done") } // now lets do some normal Groovy again file = new File("target/AntTest/groovy/util/AntTest.groovy") assert file.exists() Saturday, March 12, 2011
  • 52.
    Gradle • Easy to get started with • Bye bye ‘copy-paste’-pattern • Declarative OR Build by Convention • Extremely Extendable • Integrates with Ivy for dependency management Saturday, March 12, 2011
  • 53.
    Gradle: Highlights • Easy for the first 80% of functionality • ...easy for the 20% last as well • Keeps track of what’s changed • Works everywhere thanks to the Gradle Wrapper Saturday, March 12, 2011
  • 54.
    Gradle: Simply Groovy apply plugin: 'groovy' apply plugin: 'application' repositories { mavenCentral() } dependencies { groovy 'org.codehaus.groovy:groovy-all:1.7.9' } mainClassName='HelloWorld' Saturday, March 12, 2011
  • 55.
    Gradle: Multiproject • Head out to the code... :) Saturday, March 12, 2011
  • 56.
  • 57.
    Griffon • Grails for the desktop • Early days but lots of plugins • DSL for Swing • Extends SwingBuilder Saturday, March 12, 2011
  • 58.
    GroovyServ • Speeds up execution of Groovy scripts • Groovy for small utils finally valid! Saturday, March 12, 2011
  • 59.
    GroovyServ: Pretty XML on the commandline #!/usr/bin/env groovyclient println(prettyPrintXml(System.in.text)) def prettyPrintXml(text) { def xmlNode = new XmlParser().parseText(text) def writer = new StringWriter() def printer = new XmlNodePrinter(new PrintWriter(writer)) printer.preserveWhitespace = true printer.print(xmlNode) writer.toString().trim() } Saturday, March 12, 2011
  • 60.
    Links • Groovy • http://groovy.codehaus.org/ • Groovy Goodness (great tips and trix) • http://mrhaki.blogspot.com/ • Groovy Web Console (on Appengine) • http://groovyconsole.appspot.com/ • My blog • http://xlson.com/ • SweGUG • http://groups.google.com/group/swegug Saturday, March 12, 2011