a tour through the groovy ecosystem

60
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

Upload: leonard-axelsson

Post on 06-May-2015

1.853 views

Category:

Technology


0 download

DESCRIPTION

Groovy presentation from Dyncon 2011 in Sweden

TRANSCRIPT

Page 2: A Tour Through the Groovy Ecosystem

Leonard Axelsson

• Groovy developer since 2007• Co-Founder of SweGUG

–Swedish Groovy User Group• Speaker at Javaforum,

GTUG, Agical Geeknight, JFokus, SweGUG

• Developer/Consultant at Agical

@xlsonhttp://xlson.com/

Saturday, March 12, 2011

Page 3: A Tour Through the Groovy Ecosystem

a long long time ago (4 years or so ;)

Saturday, March 12, 2011

Page 4: A Tour Through the Groovy Ecosystem

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

Page 5: A Tour Through the Groovy Ecosystem

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

Page 6: A Tour Through the Groovy Ecosystem

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

Page 7: A Tour Through the Groovy Ecosystem

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 DSLsnew DateDSL().last.day.in.december( 2009 )

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

Saturday, March 12, 2011

Page 8: A Tour Through the Groovy Ecosystem

The obligatory Hello World

Saturday, March 12, 2011

Page 9: A Tour Through the Groovy Ecosystem

How many in here know Groovy?

Saturday, March 12, 2011

Page 10: A Tour Through the Groovy Ecosystem

Ok, so how many in here know some Java?

Saturday, March 12, 2011

Page 11: A Tour Through the Groovy Ecosystem

class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); }}

HelloWorld.java

Saturday, March 12, 2011

Page 12: A Tour Through the Groovy Ecosystem

class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); }}

HelloWorld.groovy

Saturday, March 12, 2011

Page 13: A Tour Through the Groovy Ecosystem

class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); }}

Removing ...

Saturday, March 12, 2011

Page 14: A Tour Through the Groovy Ecosystem

class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!") }}

Removing ...

Saturday, March 12, 2011

Page 15: A Tour Through the Groovy Ecosystem

class HelloWorld { public static void main(String[] args) { println("Hello World!") }}

Removing ...

Saturday, March 12, 2011

Page 16: A Tour Through the Groovy Ecosystem

println("Hello World!")

Removing ...

Saturday, March 12, 2011

Page 17: A Tour Through the Groovy Ecosystem

println "Hello World!"

This is it

Saturday, March 12, 2011

Page 18: A Tour Through the Groovy Ecosystem

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

Page 19: A Tour Through the Groovy Ecosystem

Primitives are objects to// Normal stringString message = 'got $5?'

// Double quoted string supports macrosString longerMessage = "Have you $message"

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

/Leo"""

println messageprintln longerMessageprintln email

int a = 5long b = 1float f = 5.4double d = 5.4

Saturday, March 12, 2011

Page 20: A Tour Through the Groovy Ecosystem

Plain Old Groovy Objects

Saturday, March 12, 2011

Page 21: A Tour Through the Groovy Ecosystem

POGO’s

• Properties

• getters and setters are created automatically

Saturday, March 12, 2011

Page 22: A Tour Through the Groovy Ecosystem

POGO’s

• Properties

• getters and setters are created automatically

• Named Parameters

• clarifies intent

Saturday, March 12, 2011

Page 23: A Tour Through the Groovy Ecosystem

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 lastnameanders.setLastname("Sundstedt")assert anders.lastname == "Sundstedt"

Saturday, March 12, 2011

Page 24: A Tour Through the Groovy Ecosystem

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 lastnameanders.lastname = "Sundstedt"assert anders.lastname == "tdetsdnuS"

Saturday, March 12, 2011

Page 25: A Tour Through the Groovy Ecosystem

Built in syntax for lists and maps

Saturday, March 12, 2011

Page 26: A Tour Through the Groovy Ecosystem

Lists

def names = ['Leonard', 'Anna', 'Anders']assert names instanceof Listassert names.size() == 3assert names[0] == 'Leonard'

List syntax:

Saturday, March 12, 2011

Page 27: A Tour Through the Groovy Ecosystem

Mapsdef map = [name: 'Leonard', lastname: 'Axelsson']assert map.name == 'Leonard'assert map['lastname'] == 'Axelsson'

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

Key: name, Value: LeonardKey: lastname, Value: Axelsson

Output:

Saturday, March 12, 2011

Page 28: A Tour Through the Groovy Ecosystem

each, find and findAllclass 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 namesages.each { println "$it.name $it.lastname" }

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

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

Saturday, March 12, 2011

Page 29: A Tour Through the Groovy Ecosystem

Putting the basics together

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

Saturday, March 12, 2011

Page 30: A Tour Through the Groovy Ecosystem

AST TransformationsCompile-time meta programming

Saturday, March 12, 2011

Page 31: A Tour Through the Groovy Ecosystem

@Log

import groovy.util.logging.*

@Logclass LogDemo { def usesLogger() { log.info "Uses the log annotation." } static void main(String[] args) { new LogDemo().usesLogger() }}

Saturday, March 12, 2011

Page 32: A Tour Through the Groovy Ecosystem

@Immutableimport groovy.transform.*

@Immutableclass 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

Page 33: A Tour Through the Groovy Ecosystem

@EqualsAndHashCode

import groovy.transform.*

@EqualsAndHashCodeclass 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

Page 34: A Tour Through the Groovy Ecosystem

Mapping the ecosystem

So, we’ve already started, but let’s do some more sightseeing...

Saturday, March 12, 2011

Page 35: A Tour Through the Groovy Ecosystem

GPars• Parallelization framework

• Features

• Actors

• Agents

• Dataflow

• Parallell Collection Processing

Saturday, March 12, 2011

Page 36: A Tour Through the Groovy Ecosystem

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

GPars

Saturday, March 12, 2011

Page 37: A Tour Through the Groovy Ecosystem

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

Saturday, March 12, 2011

Page 38: A Tour Through the Groovy Ecosystem

@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

Page 39: A Tour Through the Groovy Ecosystem

Web

Saturday, March 12, 2011

Page 40: A Tour Through the Groovy Ecosystem

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

Page 41: A Tour Through the Groovy Ecosystem

Grails

• Convention Over Configuration

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

• Stands upon the shoulders of giants

• Rich plugin system

More about Grails tomorrow at 13:40-14:20

with Henk Jurriens! :)

Saturday, March 12, 2011

Page 42: A Tour Through the Groovy Ecosystem

Testing,what to say about testing...• Spock

• EasyB

• GroovyTestCase

• MockFor()

• Expandos and Maps

• Geb

• SoapUI

• Groovy Remote Control

Saturday, March 12, 2011

Page 43: A Tour Through the Groovy Ecosystem

Spock

• Great testing framework

• Easy to read (and write)

Saturday, March 12, 2011

Page 44: A Tour Through the Groovy Ecosystem

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

Page 45: A Tour Through the Groovy Ecosystem

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

Page 46: A Tour Through the Groovy Ecosystem

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

Page 47: A Tour Through the Groovy Ecosystem

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

Page 48: A Tour Through the Groovy Ecosystem

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

Page 49: A Tour Through the Groovy Ecosystem

Building

Saturday, March 12, 2011

Page 50: A Tour Through the Groovy Ecosystem

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

Page 51: A Tour Through the Groovy Ecosystem

AntBuilderdef ant = new AntBuilder()

// lets just call one taskant.echo("hello")

// here is an example of a block of Ant inside GroovyMarkupant.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 againfile = new File("target/AntTest/groovy/util/AntTest.groovy")assert file.exists()

Saturday, March 12, 2011

Page 52: A Tour Through the Groovy Ecosystem

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

Page 53: A Tour Through the Groovy Ecosystem

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

Page 54: A Tour Through the Groovy Ecosystem

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

Page 55: A Tour Through the Groovy Ecosystem

Gradle:Multiproject

• Head out to the code... :)

Saturday, March 12, 2011

Page 56: A Tour Through the Groovy Ecosystem

Other goodies

Saturday, March 12, 2011

Page 57: A Tour Through the Groovy Ecosystem

Griffon

• Grails for the desktop

• Early days but lots of plugins

• DSL for Swing

• Extends SwingBuilder

Saturday, March 12, 2011

Page 58: A Tour Through the Groovy Ecosystem

GroovyServ

• Speeds up execution of Groovy scripts

• Groovy for small utils finally valid!

Saturday, March 12, 2011

Page 59: A Tour Through the Groovy Ecosystem

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

Page 60: A Tour Through the Groovy Ecosystem

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