A Tour Through the Groovy Ecosystem
Upcoming SlideShare
Loading in...5
×
 

A Tour Through the Groovy Ecosystem

on

  • 2,173 views

Groovy presentation from Dyncon 2011 in Sweden

Groovy presentation from Dyncon 2011 in Sweden

Statistics

Views

Total Views
2,173
Views on SlideShare
2,156
Embed Views
17

Actions

Likes
1
Downloads
11
Comments
0

3 Embeds 17

http://lanyrd.com 11
https://www.linkedin.com 4
http://www.linkedin.com 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

A Tour Through the Groovy Ecosystem A Tour Through the Groovy Ecosystem Presentation Transcript

  • A Tour Through the Groovy Ecosystem at Examples available on Github https://github.com/xlson/presentations/tree/master/ groovy-ecosystem-dyncon_2011Saturday, 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/ AgicalSaturday, 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.5Saturday, 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 • EmbeddableSaturday, 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=27001Saturday, March 12, 2011
  • The obligatory Hello WorldSaturday, 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 JDKSaturday, 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 emailSaturday, March 12, 2011
  • Plain Old Groovy ObjectsSaturday, March 12, 2011
  • POGO’s • Properties • getters and setters are created automaticallySaturday, March 12, 2011
  • POGO’s • Properties • getters and setters are created automatically • Named Parameters • clarifies intentSaturday, 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 mapsSaturday, March 12, 2011
  • Lists List syntax: def names = [Leonard, Anna, Anders] assert names instanceof List assert names.size() == 3 assert names[0] == LeonardSaturday, 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: AxelssonSaturday, 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() == 2Saturday, 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 programmingSaturday, 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 userSaturday, 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 == user2Saturday, 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 ProcessingSaturday, 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 scriptsSaturday, March 12, 2011
  • WebSaturday, 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 systemSaturday, 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 systemSaturday, March 12, 2011
  • Testing, what to say about testing... • Spock • EasyB • GroovyTestCase • MockFor() • Expandos and Maps • Geb • SoapUI • Groovy Remote ControlSaturday, 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 objectsSaturday, 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
  • BuildingSaturday, March 12, 2011
  • AntBuilder • Gives you the power of Ant in Groovy • ..the power of what? • Well, platform independent file handling among other thingsSaturday, 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 managementSaturday, 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 WrapperSaturday, 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=HelloWorldSaturday, March 12, 2011
  • Gradle: Multiproject • Head out to the code... :)Saturday, March 12, 2011
  • Other goodiesSaturday, March 12, 2011
  • Griffon • Grails for the desktop • Early days but lots of plugins • DSL for Swing • Extends SwingBuilderSaturday, 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/swegugSaturday, March 12, 2011