![Page 1: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/1.jpg)
Groovy updateand Gaelyk,
a lightweight toolkit for Google App Engine
![Page 2: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/2.jpg)
Groovy updateand Gaelyk,
a lightweight toolkit for Google App Engine
![Page 3: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/3.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Guillaume Laforge / @glaforge
• Groovy Project Manager• Head of Groovy Development
at SpringSource• Initiator of the Grails framework• Founder of the Gaelyk toolkit• Co-author of Groovy in Action• Member of «Les Cast Codeurs» podcast
• Speaker: JavaOne, QCon, JavaZone, Sun TechDays, Devoxx, The Spring Experience, SpringOne2GX, JAX, Dynamic Language World, IJTC, and more...
2
![Page 4: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/4.jpg)
![Page 5: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/5.jpg)
![Page 6: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/6.jpg)
![Page 7: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/7.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Agenda
•Past–Groovy 1.6 flashback
•Present–Groovy 1.7 novelties–A few Groovy 1.7.x refinements
•Future–What’s cooking for 1.8 and beyond
4
![Page 8: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/8.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
But first... some figures...
5
0
50000
100000
150000
200000
déc.-07 févr.-08 avr.-08 juin-08 août-08 oct.-08 janv.-09 mars-09 mai-09 juil.-09 sept.-09 nov.-09 janv.-10 mars-10 mai-10 juil.-10
Groovy downloads per monthDownloads Moving Average (year)
![Page 9: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/9.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
But first... some figures...
5
0
50000
100000
150000
200000
déc.-07 févr.-08 avr.-08 juin-08 août-08 oct.-08 janv.-09 mars-09 mai-09 juil.-09 sept.-09 nov.-09 janv.-10 mars-10 mai-10 juil.-10
Groovy downloads per monthDownloads Moving Average (year)
![Page 10: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/10.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
But first... some figures...
5
0
50000
100000
150000
200000
déc.-07 févr.-08 avr.-08 juin-08 août-08 oct.-08 janv.-09 mars-09 mai-09 juil.-09 sept.-09 nov.-09 janv.-10 mars-10 mai-10 juil.-10
Groovy downloads per monthDownloads Moving Average (year)
Groovy 1.5
![Page 11: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/11.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
But first... some figures...
5
0
50000
100000
150000
200000
déc.-07 févr.-08 avr.-08 juin-08 août-08 oct.-08 janv.-09 mars-09 mai-09 juil.-09 sept.-09 nov.-09 janv.-10 mars-10 mai-10 juil.-10
Groovy downloads per monthDownloads Moving Average (year)
Groovy 1.5
![Page 12: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/12.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
But first... some figures...
5
0
50000
100000
150000
200000
déc.-07 févr.-08 avr.-08 juin-08 août-08 oct.-08 janv.-09 mars-09 mai-09 juil.-09 sept.-09 nov.-09 janv.-10 mars-10 mai-10 juil.-10
Groovy downloads per monthDownloads Moving Average (year)
Groovy 1.5
G2Oneacquisition
![Page 13: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/13.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
But first... some figures...
5
0
50000
100000
150000
200000
déc.-07 févr.-08 avr.-08 juin-08 août-08 oct.-08 janv.-09 mars-09 mai-09 juil.-09 sept.-09 nov.-09 janv.-10 mars-10 mai-10 juil.-10
Groovy downloads per monthDownloads Moving Average (year)
Groovy 1.5
G2Oneacquisition
![Page 14: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/14.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
But first... some figures...
5
0
50000
100000
150000
200000
déc.-07 févr.-08 avr.-08 juin-08 août-08 oct.-08 janv.-09 mars-09 mai-09 juil.-09 sept.-09 nov.-09 janv.-10 mars-10 mai-10 juil.-10
Groovy downloads per monthDownloads Moving Average (year)
Groovy 1.5
G2Oneacquisition
Groovy 1.6
![Page 15: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/15.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
But first... some figures...
5
0
50000
100000
150000
200000
déc.-07 févr.-08 avr.-08 juin-08 août-08 oct.-08 janv.-09 mars-09 mai-09 juil.-09 sept.-09 nov.-09 janv.-10 mars-10 mai-10 juil.-10
Groovy downloads per monthDownloads Moving Average (year)
Groovy 1.5
G2Oneacquisition
Groovy 1.6
![Page 16: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/16.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
But first... some figures...
5
0
50000
100000
150000
200000
déc.-07 févr.-08 avr.-08 juin-08 août-08 oct.-08 janv.-09 mars-09 mai-09 juil.-09 sept.-09 nov.-09 janv.-10 mars-10 mai-10 juil.-10
Groovy downloads per monthDownloads Moving Average (year)
Groovy 1.5
G2Oneacquisition
Groovy 1.6
Groovy 1.7
![Page 17: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/17.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
But first... some figures...
5
0
50000
100000
150000
200000
déc.-07 févr.-08 avr.-08 juin-08 août-08 oct.-08 janv.-09 mars-09 mai-09 juil.-09 sept.-09 nov.-09 janv.-10 mars-10 mai-10 juil.-10
Groovy downloads per monthDownloads Moving Average (year)
Groovy 1.5
G2Oneacquisition
Groovy 1.6
Groovy 1.7
185K
![Page 18: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/18.jpg)
looking into the Past
![Page 19: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/19.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Big highlights of Groovy 1.6
• Greater compile-time and runtime performance• Multiple assignments• Optional return for if/else and try/catch/finally• Java 5 annotation definition• AST Transformations• The Grape module and dependency system• Various Swing related improvements• JMX Builder• Metaprogramming additions• JSR-223 scripting engine built-in• Out-of-the-box OSGi support
7
![Page 20: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/20.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Big highlights of Groovy 1.6
• Greater compile-time and runtime performance• Multiple assignments• Optional return for if/else and try/catch/finally• Java 5 annotation definition• AST Transformations• The Grape module and dependency system• Various Swing related improvements• JMX Builder• Metaprogramming additions• JSR-223 scripting engine built-in• Out-of-the-box OSGi support
8
![Page 21: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/21.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Multiple assignement
//multipleassignmentdef(a,b)=[1,2]asserta==1&&b==2
//withtypedvariablesdef(intc,Stringd)=[3,"Hi"]assertc==3&&d=="Hi"
defgeocode(Stringplace){[48.8,2.3]}deflat,lng//assignmenttoexistingvariables(lat,lng)=geocode('Paris')
//classicalvariableswapingexample(a,b)=[b,a]
9
![Page 22: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/22.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
More optional return
//optionalreturnforifstatements
defm1(){if(true)1else0}assertm1()==1
//optionalreturnfortry/catch/finally
defm2(bool){try{if(bool)thrownewException()
1}catch(any){2}finally{3}}assertm2(true)==2&&m2(false)==1
10
![Page 23: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/23.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
AST Transformation (1/2)
• Groovy 1.6 introduced AST Transformations–AST: Abstract Syntax Tree
• Ability to change what’s being compiled by the Groovy compiler... at compile time–No runtime impact!–Change the semantics of your programs! Even hijack the
Groovy syntax!–Implementing recurring patterns in your code base–Remove boiler-plate code
• Two kinds: global and local–triggered by annotations
11
![Page 24: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/24.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
AST Transformations (2/2)
• Transformations introduced in 1.6–@Singleton–@Immutable, @Lazy, @Delegate–@Newify–@Category, @Mixin–@PackageScope–Swing’s @Bindable and @Vetoable–Grape’s own @Grab
12
![Page 25: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/25.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
@Immutable
• To properly implement immutable classes–No mutations — state musn’t change–Private final fields–Defensive copying of mutable components–Proper equals() / hashCode() / toString()
for comparisons or as keys in maps
@ImmutableclassCoordinates{Doublelat,lng}defc1=newCoordinates(lat:48.8,lng:2.5)
defc2=newCoordinates(48.8,2.5)assertc1==c2
13
![Page 26: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/26.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Grab a grape!
• Simple distribution and sharing of Groovy scripts• Dependencies stored locally
–Can even use your own local repositories
@Grab(group='org.mortbay.jetty',
module='jetty‐embedded',
version='6.1.0')
defstartServer(){defsrv=newServer(8080)
defctx=newContext(srv,"/",SESSIONS)
ctx.resourceBase="."
ctx.addServlet(GroovyServlet,"*.groovy")
srv.start()}
14
![Page 27: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/27.jpg)
into the Present...
![Page 28: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/28.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Big highlights of Groovy 1.7
• Anonymous Inner Classes and Nested Classes• Annotations anywhere• Grape improvements• Power Asserts• AST Viewer• AST Builder• Customize the Groovy Truth!• Rewrite of the GroovyScriptEngine• Groovy Console improvements• SQL support refinements
16
![Page 29: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/29.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Big highlights of Groovy 1.7
• Anonymous Inner Classes and Nested Classes• Annotations anywhere• Grape improvements• Power Asserts• AST Viewer• AST Builder• Customize the Groovy Truth!• Rewrite of the GroovyScriptEngine• Groovy Console improvements• SQL support refinements
17
![Page 30: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/30.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
AIC and NC
• Anonymous Inner Classes and Nested Classes
18
![Page 31: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/31.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
AIC and NC
• Anonymous Inner Classes and Nested Classes
For Javacopy’n paste
compatibility
sake :-)
18
![Page 32: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/32.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Annonymous Inner Classes
booleancalled=false
Timertimer=newTimer()
timer.schedule(newTimerTask(){
voidrun(){
called=true
}},0)
sleep100assertcalled
19
![Page 33: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/33.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Annonymous Inner Classes
booleancalled=false
Timertimer=newTimer()
timer.schedule(newTimerTask(){
voidrun(){
called=true
}},0)
sleep100assertcalled
{ called = true } as TimerTask
19
![Page 34: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/34.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Nested Classes
classEnvironment{staticclassProductionextendsEnvironment{}
staticclassDevelopmentextendsEnvironment{}
}
newEnvironment.Production()
20
![Page 35: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/35.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Anotations almost anywhere
• You can put annotations–on imports–on packages–on variable declarations
• Examples with @Grab following...
21
![Page 36: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/36.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Grape improvements (1/4)
• @Grab on import
@Grab(group='net.sf.json‐lib',
module='json‐lib',version='2.3',classifier='jdk15')importnet.sf.json.groovy.*
assertnewJsonSlurper().parseText(
newJsonGroovyBuilder().json{
book(title:"GroovyinAction",
author:"DierkKönigetal")
}.toString()).book.title=="GroovyinAction"
22
![Page 37: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/37.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Grape improvements (2/4)
• Shorter module / artifact / version parameter–Example of an annotation on a variable declaration
@Grab('net.sf.json‐lib:json‐lib:2.3:jdk15')
defbuilder=newnet.sf.json.groovy.JsonGroovyBuilder()
defbooks=builder.books{book(title:"GroovyinAction",author:"DierkKoenig")
}assertbooks.toString()=='{"books":{"book":{"title":"GroovyinAction",'+
'"author":"DierkKoenig"}}}'
23
![Page 38: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/38.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Grape improvements (3/4)
• Groovy 1.7 introduced Grab resolver–For when you need to specify a specific repository
for a given dependency
@GrabResolver(name='restlet.org',root='http://maven.restlet.org')
@Grab('org.restlet:org.restlet:1.1.6')
importorg.restlet.Restlet
24
![Page 39: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/39.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Power Asserts (1/2)
• Much better assert statement!–Invented and developed in the Spock framework
• Given this script...
defenergy=7200*10**15+1defmass=80defcelerity=300000000
assertenergy==mass*celerity**2
25
![Page 40: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/40.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Power Asserts (2/2)
• You’ll get a more comprehensible output
26
![Page 41: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/41.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Easier AST Transformations
• AST Transformations are a very powerful feature
• But are still rather hard to develop–Need to know the AST API closely
• To help with authoring your own transformations, we’ve introduced–the AST Viewer in the Groovy Console–the AST Builder
27
![Page 42: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/42.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
AST Viewer
28
![Page 43: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/43.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
AST Builder
//AbilitytobuildASTparts
//‐‐>fromaStringnewAstBuilder().buildFromString('''"Hello"'''
)
//‐‐>fromcodenewAstBuilder().buildFromCode{"Hello"}
//‐‐>fromaspecification
List<ASTNode>nodes=newAstBuilder().buildFromSpec{
block{returnStatement{
constant"Hello"
}}}
29
![Page 44: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/44.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Customize the Groovy Truth!
• Ability to customize the truth by implementing a boolean asBoolean() method
classPredicate{booleanvaluebooleanasBoolean(){value}
}
deftruePred=newPredicate(value:true)
deffalsePred=newPredicate(value:false)
asserttruePred&&!falsePred
30
![Page 45: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/45.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Groovy 1.7.x changes
• Since Groovy 1.7.0...Groovy 1.7.1, 1.7.2, 1.7.3, 1.7.4, 1.7.5 and 1.7.6 have been released already!
• Here’s what’s new!
31
![Page 46: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/46.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Grape improvements (4/4)
• Groovy 1.7.5 even further shrinks the grab resolver definition:
32
@GrabResolver('http://maven.restlet.org')
@Grab('org.restlet:org.restlet:1.1.6')
importorg.restlet.Restlet
![Page 47: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/47.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Map improvements (1/2)
//mapauto‐vificationdefm=[:].withDefault{key‐>"Default"}
assertm['z']=="Default"
assertm['a']=="Default"
//defaultsort,sortwithacomparator
m.sort()m.sort({a,b‐>a<=>b}asComparator)
//max{}andmin{}assert[a:1,b:2].max{it.value}.value==2
33
![Page 48: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/48.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Map improvements (2/2)
//beforeMap#withDefault()
defwords="onetwotwothreethreethree".split()
deffreq=[:]
words.each{if(itinfreq)freq[it]+=1elsefreq[it]=1}
34
![Page 49: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/49.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Map improvements (2/2)
//afterMap#withDefault()
defwords="onetwotwothreethreethree".split()
deffreq=[:].withDefault{k‐>0}
words.each{
freq[it]+=1
}
35
![Page 50: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/50.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
XML back to String
• Ability to retrieve the XML string from a node from an XmlSlurper GPathResult
defxml="""<books><bookisbn="12345">GroovyinAction</book>
</books>"""defroot=newXmlSlurper().parseText(xml)
defsomeNode=root.bookdefbuilder=newStreamingMarkupBuilder()
assertbuilder.bindNode(someNode).toString()==
"<bookisbn='12345'>GroovyinAction</book>"
36
![Page 51: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/51.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Currying improvements
//rightcurryingdefdivide={a,b‐>a/b}
defhalver=divide.rcurry(2)
asserthalver(8)==4//curryingn‐thparameterdefjoinWithSeparator={one,sep,two‐>
one+sep+two}defjoinWithComma=joinWithSeparator.ncurry(1,',')
assertjoinWithComma('a','b')=='a,b'
37
![Page 52: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/52.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Date improvements
importstaticjava.util.Calendar.*
//converttocalendardefcal=newDate().toCalendar()
//updateadate(oracalendar)
cal.set(year:cal[YEAR]+1)
cal[MONTH]=MARCH
//createanewdate(oracalendar)fromone
defnextYear=cal.updated(year:cal[YEAR]+1)
38
![Page 53: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/53.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
New String methods
println"""defmethod(){return'bar'}""".stripIndent()
println"""|defmethod(){|return'bar'|}""".stripMargin('|')
//string"translation"(UNIXtr)
assert'hello'.tr('z‐a','Z‐A')=='HELLO'
assert'HelloWorld!'.tr('a‐z','A')=='HAAAAWAAAA!'
assert'HelloWorld!'.tr('lloo','1234')=='He224W4r2d!'
//capitalizethefirstletter
assert'h'.capitalize()=='H'
assert'hello'.capitalize()=='Hello'
assert'helloworld'.capitalize()=='Helloworld'
//tab/space(un)expansion(UNIXexpandcommand)
assert'1234567\t8\t'.expand()=='12345678'
assert'x'.unexpand()=='x\t'
39
![Page 54: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/54.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Map supports isCase()
40
defm=[a:1,b:2]defval='a'
switch(val){casem:"keyinmap";break
//equivalentto//case{valinm}:...
default:"notinmap"}
![Page 55: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/55.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
(G)String to Enum coercion
41
enumColor{red,green,blue}
//coercionwithasdefr="red"asColor
//implicitcoercionColorb="blue"
//withGStringstoodefg="${'green'}"asColor
![Page 56: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/56.jpg)
...and beyond!
![Page 57: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/57.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Groovy 1.8 & beyond
• Still subject to discussion• Always evolving roadmap• Things may change!
43
![Page 58: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/58.jpg)
What’s cooking?
![Page 59: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/59.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
What we’re working on
• More runtime performance improvements• Closures
–annotation parameterscomposition, memoization, and trampoline
• Native JSON support–builder and parser
• New AST transformations• Gradle build• Modularizing Groovy• Align with JDK 7 / Java 7 / Project Coin• Enhanced DSL support
45
![Page 60: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/60.jpg)
![Page 61: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/61.jpg)
G
![Page 62: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/62.jpg)
![Page 63: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/63.jpg)
![Page 64: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/64.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
An example, with Fibonacci
48
![Page 65: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/65.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
An example, with Fibonacci
• Known example of worst case performance for Groovy
48
![Page 66: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/66.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
An example, with Fibonacci
• Known example of worst case performance for Groovy
48
![Page 67: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/67.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
An example, with Fibonacci
• Known example of worst case performance for Groovy
• Groovy 1.7.5 vs Java–25131ms / 1110ms –22x slower!
48
![Page 68: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/68.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
An example, with Fibonacci
• Known example of worst case performance for Groovy
• Groovy 1.7.5 vs Java–25131ms / 1110ms –22x slower!
48
![Page 69: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/69.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
An example, with Fibonacci
• Known example of worst case performance for Groovy
• Groovy 1.7.5 vs Java–25131ms / 1110ms –22x slower!
• Groovy 1.8-beta-3 vs Java–1871ms / 1110ms–only 68% slower
48
![Page 70: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/70.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
An example, with Fibonacci
• Known example of worst case performance for Groovy
• Groovy 1.7.5 vs Java–25131ms / 1110ms –22x slower!
• Groovy 1.8-beta-3 vs Java–1871ms / 1110ms–only 68% slower
48
13x
![Page 71: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/71.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Optimizations for int
• Currently, the optimizations cover most of native operations on primitive ints–Be careful, your mileage may vary
• To come next–optimizations for doubles–improving array accesses–then other primitives optimizations–and mixed cases of primitives
49
![Page 72: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/72.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Closure annotation parameters
• Groovy 1.5 brought Java 5 annotations
• What if... we could go beyond what Java offered?–In 1.7, we can put annotations on packages, imports and
variable declarations–But annotations are still limited in terms of parameters
they allow
• Here comes closure annotation parameters!–Groovy 1.8 will give us the ability to access annotation
with closure parameters at runtime
50
![Page 73: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/73.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
GContracts
• Closures are already allowed in the Groovy 1.7 Antlr grammar–André Steingreß created GContracts,
a «design by contract» module
//aclassinvariant@Invariant({name.size()>0&&age>ageLimit()})
classPerson{Stringname;intage}
//amethodpre‐condition@Requires({message!=null})voidgreet(Stringmessage){...}
//amethodpost‐condition@Ensures({returnResult%2==0})
intevenResult(){...}
51
![Page 74: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/74.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Closure composition
• Functional flavor!
52
defplus2={it+2}deftimes3={it*3}defcomposed1=plus2<<times3assertcomposed1(3)==11assertcomposed1(4)==plus2(times3(4))
defcomposed2=times3<<plus2assertcomposed2(3)==15assertcomposed2(5)==times3(plus2(5))
//reversecompositionassertcomposed1(3)==(times3>>plus2)(3)
![Page 75: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/75.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Closure memoization
• Memoization: remember the outcome of previous (ideally side-effect free) invocations
53
defc={a,b‐>sleep1000;a+b}.memoize()
assertc(1,2)==3//after1000ms
assertc(1,2)==3//returnimmediately
//otherforms://atleast10invocationscached
defcAtLeast={...}.memoizeAtLeast(10)
//atmost10invocationscacheddefcAtMost={...}.memoizeAtMost(10)
//between10and20invocationscached
defcAtLeast={...}.memoizeBetween(10,20)
![Page 76: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/76.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Closure trampoline
• No more infamous StackOvervlow errors for deeply recursive algorithms–if you use closure trampolines explicitely
54
deffactfact={intn,BigIntegeraccu‐>
n>1?fact.trampoline(n‐1,n*accu):accu
}.trampoline()
deffactorial={intn‐>fact(n,1G)}
assertfactorial(1)==1assertfactorial(3)==6assertfactorial(1000)==402387260077...
![Page 77: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/77.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
New AST xforms (1/2)
• Many new transformations coming up for removing even more boiler plate code
55
@Log inject a logger in your classes@Field creates a field in your scripts@PackageScope improvements (methods & fields)@Synchronized providing safer synchronization semantics@InheritConstructor ex. when extending Exception@IndexedProperties JavaBeans indexed property support@AutoClone automatic cloning of your beans@AutoExternalizable automatic externalization of your beans
![Page 78: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/78.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
New AST xforms (2/2)
56
@ThreadInterrupt makes a script interruptible@TimedInterrupt interrupt after a period of time@ConditionalInterrupt interrupt with a custom condition
@Canonical adds equals, hashCode, toString, ctor- @EqualsAndHashCode just equals and hashCode- @ToString just toString- @TupleConstructor adds a «tuple» constructor
![Page 79: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/79.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Java 7 / 8 / Project Coin
• Alignment with JDK 7 will come in Groovy 1.9• JSR-292 InvokeDynamic• Simple Closures (8)
• Proposals from Project Coin–Strings in switch (7)–Automatic Resource Management (7)–Improved generics type inference (diamond <>) (7)–Simplified varargs method invocation (7)–Better integral literals (7)–Language support for collections (8?)
57
![Page 80: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/80.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Java 7 / 8 / Project Coin
• Alignment with JDK 7 will come in Groovy 1.9• JSR-292 InvokeDynamic• Simple Closures (8)
• Proposals from Project Coin–Strings in switch (7)–Automatic Resource Management (7)–Improved generics type inference (diamond <>) (7)–Simplified varargs method invocation (7)–Better integral literals (7)–Language support for collections (8?)
57
![Page 81: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/81.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Java 7 / 8 / Project Coin
• Alignment with JDK 7 will come in Groovy 1.9• JSR-292 InvokeDynamic• Simple Closures (8)
• Proposals from Project Coin–Strings in switch (7)–Automatic Resource Management (7)–Improved generics type inference (diamond <>) (7)–Simplified varargs method invocation (7)–Better integral literals (7)–Language support for collections (8?)
57
![Page 82: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/82.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Java 7 / 8 / Project Coin
• Alignment with JDK 7 will come in Groovy 1.9• JSR-292 InvokeDynamic• Simple Closures (8)
• Proposals from Project Coin–Strings in switch (7)–Automatic Resource Management (7)–Improved generics type inference (diamond <>) (7)–Simplified varargs method invocation (7)–Better integral literals (7)–Language support for collections (8?)
57
![Page 83: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/83.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Java 7 / 8 / Project Coin
• Alignment with JDK 7 will come in Groovy 1.9• JSR-292 InvokeDynamic• Simple Closures (8)
• Proposals from Project Coin–Strings in switch (7)–Automatic Resource Management (7)–Improved generics type inference (diamond <>) (7)–Simplified varargs method invocation (7)–Better integral literals (7)–Language support for collections (8?)
57
![Page 84: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/84.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Improved DSL support
• GEP-3: an extended command expression DSL–Groovy Extension Proposal #3
• Command expressions–basically top-level statements without parens–combine named and non-named arguments in the mix
•for nicer Domain-Specific Languages–(methodName arguments)*
58
![Page 85: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/85.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Before GEP-3
• The idea: extend command-expressions, beyond top-level statements, for chained method calls
• Before
send("Hello").to("Graeme")
check(that:margherita).tastes(good)
sell(100.shares).of(MSFT)
take(2.pills).of(chloroquinine).after(6.hours)
wait(10.minutes).and(execute{})
blend(red,green).of(acrylic)
59
![Page 86: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/86.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
With GEP-3
• The idea: extend command-expressions, beyond top-level statements, for chained method calls
• After
send"Hello"to"Graeme"
checkthat:margheritatastesgood
sell100.sharesofMSFT
take2.pillsofchloroquinineafter6.hours
wait10.minutesandexecute{}
blendred,greenofacrylic
60
![Page 87: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/87.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
With GEP-3
• The idea: extend command-expressions, beyond top-level statements, for chained method calls
• After
send"Hello"to"Graeme"
checkthat:margheritatastesgood
sell100.sharesofMSFT
take2.pillsofchloroquinineafter6.hours
wait10.minutesandexecute{}
blendred,greenofacrylic
Less parens& commas
60
![Page 88: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/88.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
The pattern
• A repetition of–method name–arguments (mix of named and normal)
61
checkthat:margheritatastesgood
methodname
methodname
parameternamed parameter
![Page 89: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/89.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Summary
• No need to wait for Java 7, 8, 9...–closures, properties, interpolated strings, extended
annotations, metaprogramming, [YOU NAME IT]...
62
![Page 90: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/90.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Summary
• No need to wait for Java 7, 8, 9...–closures, properties, interpolated strings, extended
annotations, metaprogramming, [YOU NAME IT]...
Groovy’s still
innovative
since 2003!
62
![Page 91: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/91.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Summary
• No need to wait for Java 7, 8, 9...–closures, properties, interpolated strings, extended
annotations, metaprogramming, [YOU NAME IT]...
Groovy’s still
innovative
since 2003!
62
![Page 92: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/92.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Q and A
![Page 93: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/93.jpg)
CloudComputing
![Page 94: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/94.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
IaaS, PaaS, SaaS
• Software as a Service–Gmail, SalesForce.com
• Platform as a Service–Google App Engine
• Infrastructure as a Service–Amazon EC2
SaaS
PaaSIaaS
65
![Page 95: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/95.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
IaaS, PaaS, SaaS
• Software as a Service–Gmail, SalesForce.com
• Platform as a Service–Google App Engine
• Infrastructure as a Service–Amazon EC2
SaaS
PaaSIaaS
65
![Page 96: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/96.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
IaaS, PaaS, SaaS
• Software as a Service–Gmail, SalesForce.com
• Platform as a Service–Google App Engine
• Infrastructure as a Service–Amazon EC2
SaaS
PaaSIaaS
65
![Page 97: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/97.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Google App Engine
• Google’s PaaS solution• Run your app on Google’s infrastructure
• Initially just Python supported
• Java supported added too–Sandboxed JVM–Jetty servlet container
• Several JVM-compatible language supported
66
![Page 98: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/98.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Key aspects
• You can use most of your usual web frameworks for developping apps on App Engine Java–A WAR file, basically! (an exploded war actually)
– Uploading to the cloud by sending deltas of changes
• No OS image, or software to install– Unlike with Amazon EC2
• All the scaling aspects are handled for you– Database / session replication, load balancing...
• There are quotas, but you need a high traffic application to start being charged–Free to get started
67
![Page 99: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/99.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Available services
•Memcache– JCache implementation
– Save on CPU and DB
•URL Fetch– Access remote resources– HttpUrlConnection
•Mail– Support both incoming and
outgoing emails
•Images– Resize, crop, rotate...
•XMPP
– Send / receive Jabber messages (GTalk)
•User– Use Google’s user/
authentication system
– OAuth support
•Cron & Task queues– Schedule tasks at regular
intervals
– Queue units of work
•Blobstore– For storing large content
• And much more...
68
![Page 100: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/100.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Limitations
•Not our usual relational database–key / value datastore
•30 seconds request duration limit
• Forbidden to –write on the file system–create threads–use raw sockets–issue system calls–use IO / Swing / etc. directly
•There’s a whitelist of classes allowed
• Number of files and their size are limited
69
![Page 101: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/101.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Quotas
70
![Page 102: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/102.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Quotas (1/2)
•Bandwidth–1,3M requests/day–1GB/day in/out–6.5 CPU hours/day
•Datastore–10M calls–1GB/day–12GB in / 115GB out–60 CPU hours/day
•Mail–7K calls/day–2K recepients/day–5K emails/day–2K attachments–100MB of attachments
•URL Fetch–657K calls/day–4GB in/out /day
71
![Page 103: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/103.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Quotas (2/2)
•XMPP–657K calls/day–4GB data sent/day–657K recepients/day–1MB invitations/day
•Image manipulation–864 calls/day–1GB in / 5GB out–2.5M transforms
•Memcache–8.6M calls/day–10GB in–50GB out
•Task queues–100K calls
72
![Page 104: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/104.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Quotas (2/2)
•XMPP–657K calls/day–4GB data sent/day–657K recepients/day–1MB invitations/day
•Image manipulation–864 calls/day–1GB in / 5GB out–2.5M transforms
•Memcache–8.6M calls/day–10GB in–50GB out
•Task queues–100K calls
72
Outdated figures
![Page 105: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/105.jpg)
The Datastore
![Page 106: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/106.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
The datastore...
•Not your father’s relational database! «NoSQL»
• Distributed key / value store– Based on Google’s «BigTable»
– Schema-less approach
• Supporting– Transactions and partitioning
– Hierarchies through entity groups
• Data access APIs– JPA and JDO
• but adds a big request load time factor
– Direct low-level APIs
74
![Page 107: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/107.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
...and its «limitations»
• You’re not using SQL–No joins–No database constraints–No aggregation functions (count, avg...)
• In a query, you can only filter on one column for inequality
• Transactions only available in entity groups
• You can only update an entity once in a transaction
75
![Page 108: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/108.jpg)
Nice dashboard
![Page 111: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/111.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Gaelyk 0.6 released!
78
• Even a 0.6.1...
![Page 112: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/112.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
• Gaelyk is a lightweight Groovy toolkit on top of the Google App Engine Java SDK
• Gaelyk builds on Groovy’s servlet support–Groovlets: Groovy scripts instead of raw servlets!–Groovy templates: JSP-like template engine–Both allow for a clean separation of views and logic
• Gaelyk provides several enhancements around the GAE Java SDK to make life easier, thanks to Groovy’s dynamic nature
79
![Page 113: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/113.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Why Groovy?
• Groovy is a dynamic language for the JVM–very flexible, malleable, expressive and concise syntax–easy to learn for Java developers
•deriving from the Java 5 grammar
–provides powerful APIs to simplify the life of developers•possibility to dynamically enrich existing APIs
–support for Groovlets and its own template engine
80
![Page 114: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/114.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 81
![Page 115: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/115.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 81
![Page 116: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/116.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 81
![Page 117: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/117.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 81
![Page 118: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/118.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 81
![Page 119: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/119.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 81
![Page 120: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/120.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 81
![Page 121: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/121.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 81
![Page 122: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/122.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 81
![Page 123: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/123.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 81
![Page 124: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/124.jpg)
First steps...
• Go to http://gaelyk.appspot.com
• Download the template project
• Put your first Groovlet in /WEB-INF/groovy
• And your templates in /WEB-INF/pages
• And you’re ready to go!
• Launch dev_appserver.sh
• Go to http://localhost:8080/
![Page 125: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/125.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
The web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<listener> <listener-class>groovyx.gaelyk.GaelykServletContextListener</servl
et-class>
</listener> <servlet> <servlet-name>GroovletServlet</servlet-name>
<servlet-class>groovyx.gaelyk.GaelykServlet</servlet-class>
</servlet> <servlet> <servlet-name>TemplateServlet</servlet-name>
<servlet-class>groovyx.gaelyk.GaelykTemplateServlet</servlet-class>
</servlet>
<servlet-mapping> <servlet-name>GroovletServlet</servlet-name>
<url-pattern>*.groovy</url-pattern>
</servlet-mapping> <servlet-mapping> <servlet-name>TemplateServlet</servlet-name>
<url-pattern>*.gtpl</url-pattern>
</servlet-mapping></web-app>
83
![Page 126: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/126.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
MVC: Groovlets and templates
Groovlets(controllers)
Templates(views)
Entities(domain)
84
![Page 127: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/127.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
A groovlet
• Instead of writing full-blown servlets, just write Groovy scripts (aka Groovlets)
def numbers = [1, 2, 3, 4]def now = new Date()
html.html { body { numbers.each { number -> p number } p now }}
85
![Page 128: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/128.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
A groovlet
• Instead of writing full-blown servlets, just write Groovy scripts (aka Groovlets)
def numbers = [1, 2, 3, 4]def now = new Date()
html.html { body { numbers.each { number -> p number } p now }}
85
Auto-reloading
![Page 129: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/129.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
A template
<html> <body> <p><% def message = "Hello World!" print message %> </p> <p><%= message %></p> <p>${message}</p> <ul> <% 3.times { %> <li>${message}</li> <% } %> </ul> </body></html>
86
![Page 130: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/130.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
A template
<html> <body> <p><% def message = "Hello World!" print message %> </p> <p><%= message %></p> <p>${message}</p> <ul> <% 3.times { %> <li>${message}</li> <% } %> </ul> </body></html>
86
Auto-reloading
![Page 131: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/131.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Shortcuts
•Google services–datastore–blobstore–memcache–capabilities–images–urlFetch–mail–userService / user–defaultQueue / queues–xmpp–namespace
•Variables available–request / response–context / application–sessions–params / headers–out / sout / html–localMode / app.*
•Methods available–include / forward /
redirect–println / print
87
![Page 132: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/132.jpg)
DEMO88
![Page 133: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/133.jpg)
Groovy sugar!
![Page 134: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/134.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Sending emails with Gaelyk
mail.send to: '[email protected]', from: '[email protected]', subject: 'Hello World', htmlBody: '<bold>Hello</bold>'
90
![Page 135: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/135.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
...compared to Java
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
try { Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("[email protected]", "Admin"));
msg.addRecipient(Message.RecipientType.TO,
new InternetAddress("[email protected]", "Mr. User"));
msg.setSubject("Hello World");
msg.setText("<bold>Hello</bold>");
Transport.send(msg);} catch (AddressException e) {}
} catch (MessagingException e) {}
91
![Page 136: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/136.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Accessing the datastore
• Direct interaction with the low-level datastore API
Entity entity = new Entity("person") // subscript notation, like when accessing a mapentity['name'] = "Guillaume Laforge" // normal property access notationentity.age = 32
entity.save() // asyncSave()entity.delete() // asyncDelete()
datastore.withTransaction { // do stuff with your entities // within the transaction}
// use the asynchronous datastore servicedatastore.async.put(entity)
92
![Page 137: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/137.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Querying to be improved...
import com.google.appengine.api.datastore.*import static com.google.appengine.api.datastore.FetchOptions.Builder.* // query the scripts stored in the datastoredef query = new Query("savedscript") // sort results by descending order of the creation datequery.addSort("dateCreated", Query.SortDirection.DESCENDING) // filters the entities so as to return only scripts by a certain authorquery.addFilter("author", Query.FilterOperator.EQUAL, params.author)
PreparedQuery preparedQuery = datastore.prepare(query) // return only the first 10 resultsdef entities = preparedQuery.asList( withLimit(10) )
93
![Page 138: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/138.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
...into something groovier?
def entities = datastore.query { select all from savedscript sort desc by dateCreated where author == params.author limit 10} as List
94
![Page 139: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/139.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
...into something groovier?
def entities = datastore.query { select all from savedscript sort desc by dateCreated where author == params.author limit 10} as List
Not Yet Implemented!
94
![Page 140: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/140.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
URL Routing system (1/4)
• You can have friendly URL mappings with the URL routing system
–You’ll have to configure the RouteFilter in web.xml
all "/aboutus", redirect: "/blog/2008/10/20/about-us"
all "/blog/@year/@month/@day/@title", forward: "/blog.groovy?year=@year&month=@month@day=@day@title=@title"
get "/blog/@year/@month/@day", forward: "/blog.groovy?year=@year&month=@month@day=@day"
get "/book/isbn/@isbn", forward: "/book.groovy?isbn=@isbn", validate: { isbn ==~ /\d{9}(\d|X)/ }
95
![Page 141: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/141.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
URL Routing system (2/4)
• You can also define caching times
–Nice for GAE’s infamous «loading requests»•less critical with GAE SDK 1.4
–ability to reserve 3 instances (billing)–warmup requests
get "/aboutus", cache: 24.hours, forward: "/aboutus.gtpl"
get "/breaking-news", cache: 1.minute, forward: "/news.groovy?last=10"
96
![Page 142: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/142.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
URL Routing system (3/4)
• Special routes for specifying–incoming emails–jabber messages
97
email to "/incomingMail.groovy"
jabber to "/incomingXmpp.groovy"
![Page 143: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/143.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
URL Routing system (4/4)
• Namespace awareness: nice for multitenancy• Capability awareness: for graceful degradation
98
// @cust customer variable could be « acme »post "/@cust/update", forward: "/update.groovy", namespace: { "ns-$cust" }
// different destinations depending on the GAE services status
get "/speakers", forward { to "/speakers.groovy" // default destination // when the datastore is not available to "/unavailable.gtpl" on DATASTORE not ENABLED // show some maintenance is upcoming to "/speakers.groovy?maintenance=true" on DATASTORE \ is SCHEDULED_MAINTENANCE}
![Page 144: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/144.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Capabilities
• Google App Engine allows you to know the status and availability of the various services–DATASTORE, DATESTORE_WRITE, MEMCACHE...–ENABLED, DISABLED, UNKNOWN,
SCHEDULED_MAINTENANCE–is() and not() methods
99
if (capabilities[DATASTORE_WRITE].is(ENABLED)) { // write some content in the datastore} else { // otherwise, redirect to some maintenance page}
![Page 145: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/145.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Task queue API
// access a configured queue using the subscript notationqueues['dailyEmailQueue'] // or using the property access notationqueues.dailyEmailQueue // you can also access the default queue with:queues.defaultdefaultQueue
// add a task to the queuequeue << [ countdownMillis: 1000, url: "/task/dailyEmail", taskName: "sendDailyEmailNewsletter", method: 'PUT', params: [date: '20090914'], payload: content]
100
![Page 146: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/146.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Jabber / XMPP support (1/3)
• Sending instant messages
String recipient = "[email protected]" // check if the user is onlineif (xmpp.getPresence(recipient).isAvailable()) { // send the message def status = xmpp.send(to: recipient, body: "Hello, how are you?") // checks the message was successfully // delivered to all the recipients assert status.isSuccessful()}
101
![Page 147: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/147.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Jabber / XMPP support (2/3)
• Sending instant messages with an XML payload
String recipient = "[email protected]" // check if the service is onlineif (xmpp.getPresence(recipient).isAvailable()) { // send the message def status = xmpp.send(to: recipient, xml: { customers { customer(id: 1) { name 'Google' } } }) // checks the message was successfully delivered to the service assert status.isSuccessful()}
102
![Page 148: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/148.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Jabber / XMPP support (2/3)
• Sending instant messages with an XML payload
String recipient = "[email protected]" // check if the service is onlineif (xmpp.getPresence(recipient).isAvailable()) { // send the message def status = xmpp.send(to: recipient, xml: { customers { customer(id: 1) { name 'Google' } } }) // checks the message was successfully delivered to the service assert status.isSuccessful()}
<customers> <customer id=’1’> <name>Google</name>
</customer></customers>
102
![Page 149: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/149.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Jabber / XMPP support (3/3)
• Receving incoming instant messages–Once you’ve configured a route for jabber messages–Add the inbound message service in appengine-web.xml
def message = xmpp.parseMessage(request)// get the body of the messagemessage.body// get the sender Jabber IDmessage.from// get the list of recipients Jabber IDsmessage.recipients // if the message is an XML document instead of a raw string messageif (message.isXml()) { // get the raw XML message.stanza // get a document parsed with XmlSlurper message.xml}
103
![Page 150: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/150.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Memcache service
• Map notation access to the cache
class Country implements Serialzable { String name } def countryFr = new Country(name: 'France') // use the subscript notation to put a country object in the cache
// (you can also use non-string keys)memcache['FR'] = countryFr // check that a key is present in the cacheif ('FR' in memcache) { // use the subscript notation to get an entry from the cache using a key
def countryFromCache = memcache['FR']}
104
![Page 151: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/151.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Closure memoization
• Cache the return values for each dinstinct invocation (for a given arguments set)
105
def countEntities = memcache.memoize { String kind -> datastore.prepare( new Query(kind) ) .countEntities()}
// first calldef totalPics = countEntityes('photos')
// second call, hitting the cachetotalPics = countEntityes('photos')
![Page 152: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/152.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Blobstore enhancements
• The blobstore allows to store some large content–images, videos, etc.
106
def blob = ...print blob.filename // contentType, creation, size
// output the content of the blob to the responseblob.serve response
// read the content of the blobblob.withReader { Reader r -> ... }blob.withStream { InputStream is -> ... }
// delete the blobblob.delete()
![Page 153: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/153.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Images service
• Readable DSL for manipulating images
107
def blobKey = ...
def image = blobKey.image.transform { resize 1600, 1200 crop 0.1, 0.1, 0.9, 0.9 horizontal flip // vertical flip too rotate 90 feeling lucky // image corrections}
def thumbnail = image.resize(100, 100)
![Page 154: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/154.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Channel Service
• For Comet-style applications
• Then in the view, in JavaScript...
108
def token = channel.createChannel('clientID')channel.send 'clientID', 'Hi!'
channel = new goog.appengine.Channel(token);socket = channel.open();socket.onmessage = function(msg) { ... }
![Page 155: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/155.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Simple plugin system (1/3)
• Gaelyk features a simple plugin system for extending your apps and share commonalities
• A plugin lets you–provide additional groovlets and templates–contribute new URL routes–add new categories–define variables in the binding–override existing binding variables–provide any static content–add new libraries–do any initialization–add before/after request hooks
109
![Page 156: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/156.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Simple plugin system (2/3)
• A plugin is actually just a zip file!–Basically, just a Gaelyk application, minus...
•the Groovy / Gaelyk / GAE JARs•the web.xml and appengine-web.xml descriptors
–But with a /WEB-INF/plugins/myplugin.groovy descriptor
• A plugin must be referenced in /WEB-INF/plugins.groovy with–install myplugin
•shortcut to /WEB-INF/plugins/myplugin.groovy
110
![Page 157: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/157.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Simple plugin system (3/3)
• An example plugin descriptor–/WEB-INF/plugins/jsonPlugin.groovy
importnet.sf.json.*importnet.sf.json.groovy.*//addnewvariablesinthebindingbinding{
jsonLibVersion="2.3"//asimplestringvariable
json=newJsonGroovyBuilder()//aninstanceofaclassofa3rd‐partyJAR
}//addnewrouteswiththeusualroutingsystemformat
routes{get"/json",forward:"/json.groovy"
}//installacategoryyou'vedevelopped
categoriesjsonlib.JsonlibCategory
before{req,resp‐>...}//orafter
//anyotherinitializationcodeyou'dneed
111
![Page 158: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/158.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Summary
![Page 159: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/159.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Summary
• Easy access to a cloud solution–Deploying Java apps, as easily as you would with PHP
• Familiar to Java folks–Your good old Servlet centric webapps style
• Pretty cheap–You need a high-trafficed website to reach the quotas
• Gaelyk provides a simplified approach to creating Servlet centric webapps in a productive manner–Leveraging Groovy’s servlet / template support and
dynamic capabilities
113
![Page 160: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/160.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
What’s coming next?
• Expect more sugar around the Datastore–An SQL-like query DSL–Easier relationship management (builder?)
• Perhaps pre-compiled groovlets and templates–Less needed since SDK 1.4
•(reserve 3 hot instances, warmup requests)
• Testing facilities specific to Gaelyk–testing utility class, Spock-specific ones...
• Anything that’ll come up in newer GAE SDK versions
114
![Page 161: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/161.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Thanks for your attention!
Guillaume Laforge
Head of Groovy Development
Email: [email protected]
Twitter: @glaforge
• References:
• http://gaelyk.appspot.com/
• http://groovy.codehaus.org/
• http://code.google.com/appengine/
115
![Page 162: Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge](https://reader034.vdocuments.us/reader034/viewer/2022052117/555875c5d8b42a8d018b52c5/html5/thumbnails/162.jpg)
Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Picture credits
Myself http://www.flickr.com/photos/romainguy/783719255/sizes/l/in/photostream/Big hat http://cdn.plussizecostumesupercenter.com/csc_inc/images/items/343x432/47703.jpgRIP http://gipsydan.files.wordpress.com/2009/11/rip.jpgHouse / past: http://www.flickr.com/photos/jasonepowell/3680030831/sizes/o/Present clock: http://www.flickr.com/photos/38629278@N04/3784344944/sizes/o/Future: http://www.flickr.com/photos/befuddledsenses/2904000882/sizes/l/Cooking: http://www.flickr.com/photos/eole/449958332/sizes/l/Snail http://www.freakingnews.com/images/app_images/snail-0.jpgUsein bolt record http://www.phombo.com/sports/usain-bolt-beijing-2008-olympics/17450/full/popular/Fibonacci figure http://cnx.org/content/m22060/latest/graphics1.jpgFibonacci face http://www.robinkelly.co.nz/site/acupil/images/lfib.jpgPuzzle: http://www.everystockphoto.com/photo.php?imageId=263521Light bulb: https://newsline.llnl.gov/retooling/mar/03.28.08_images/lightBulb.pngCheck mark: http://www.lnl.infn.it/~epics/WikiDumps/localhost/600px-symbol_ok.svg.pngPuzzle: http://www.everystockphoto.com/photo.php?imageId=263521Light bulb: https://newsline.llnl.gov/retooling/mar/03.28.08_images/lightBulb.pngGreen leaf: http://www.flickr.com/photos/epsos/3384297473/Trafic light: http://rihancompany.com/var/243/35581-Traffic%20light%20drawing.jpgButt kick: http://www.brentcsutoras.com/wp-content/uploads/2009/12/kick-ass-1.jpgLight bulb: https://newsline.llnl.gov/retooling/mar/03.28.08_images/lightBulb.pngSpeed limit : http://www.morguefile.com/archive/display/18492Warehouse : http://www.morguefile.com/archive/display/85628Check mark: http://www.lnl.infn.it/~epics/WikiDumps/localhost/600px-symbol_ok.svg.pngPuzzle: http://www.everystockphoto.com/photo.php?imageId=263521Light bulb: https://newsline.llnl.gov/retooling/mar/03.28.08_images/lightBulb.pngClouds http://www.morguefile.com/archive/display/627059http://www.morguefile.com/archive/display/625552http://www.morguefile.com/archive/display/629785Duke ok GAE http://weblogs.java.net/blog/felipegaucho/archive/ae_gwt_java.pngPython logo : http://python.org/images/python-logo.gifGaelyc cross with clouds : http://www.morguefile.com/archive/display/37889Speed limit : http://www.morguefile.com/archive/display/18492Warehouse : http://www.morguefile.com/archive/display/85628Snow foot steps : http://www.flickr.com/photos/robinvanmourik/2875929243/Sugar : http://www.flickr.com/photos/ayelie/441101223/sizes/l/Press release: http://www.napleswebdesign.net/wp-content/uploads/2009/06/press_release_11.jpg
116