Microsoft's Internet Explorer browser has no built-in vector graphics machinery required for "loss-free" gradient background themes.

Please upgrade to a better browser such as Firefox, Opera, Chrome, Safari or others with built-in vector graphics machinery and much more. (Learn more or post questions or comments at the Slide Show (S9) project site. Thanks!)

What is Groovy?

Groovy is a dynamic object-oriented (scripting) language that combines the best from Smalltalk, Python and Ruby in an all-in-one package using a Java-like syntax. Groovy is 100 % Java and compiles scripts straight to Java bytecode that run on any Java virtual machine. Groovy offers seamless and smooth Java integration: from Groovy you can access all Java libraries, you can build applets or Java beans, you can derive from Java classes in Groovy and vice versa.

First Impression – Servus Groovy Example

Groovy

$ groovy -e "print 'Servus Groovy'"

=> Servus Groovy

Java (ServusGroovy.java):

public class ServusGroovy
{
  public static void main( String args[] )
  {
     System.out.println( "Servus Groovy" );
  }
}
$ javac ServusGroovy.java
$ java ServusGroovy

=> Servus Groovy

Second Impression – Higher-Level Functions, Loops and Data Types

Groovy (HelloWorld.groovy):

 1. def country = [ "Canada", "Austria", "Brazil" ]
 2. 
 3. country.sort()
 4. 
 6. country.each { it -> println "Hello ${it}" }
$ groovy HelloWorld.groovy

=> Hello Austria
=> Hello Brazil
=> Hello Canada

or

$ groovyc HelloWorld.groovy
$ java HelloWorld

Java (HelloWorld.java):

 1. import java.util.*;
 2.
 3. public class HelloWorld
 4. {
 5.  public static void main( String args[] )
 6.  {
 7.    List country = new ArrayList();
 8.    country.add( "Canada" );
 9.    country.add( "Austria" );
10.    country.add( "Brazil" );
11.
12.     Collections.sort( country );
13.
14.     for( Iterator it = country.iterator(); it.hasNext(); )
15.        System.out.println( "Hello " + it.next() );
16.  }
17. }

Third Impression – Groovy Beans vs Java Beans

Groovy

 1. class Country
 2. {
 3.  String name
 4.  String capital
 5. }
 6.
 7. def world = [new Country(name:"Austria", capital:"Vienna"),
 8               new Country(name:"Canada", capital:"Ottawa")]
 9.
10. world.each { country -> println "The capital of ${country.name} is ${country.capital}." }

Java

 1. import java.util.*;
 2.
 3. public class Country
 4. {
 5.  private String name;
 6.  private String capital;
 7.
 8.  public String getName()    { return name; }
 9.  public String getCapital() { return capital; }
10.
11.  public void setName( String name ) { this.name = name; }
12.  public void setCapital( String capital ) { this.capital = capital; }
13.
14.  public static void main( String args[] )
15.  {
16.    Country austria = new Country();
17.    austria.setName( "Austria" );
18.    austria.setCapital( "Vienna" );
19.
20.    Country canada = new Country();
21.    canada.setName( "Canada" );
22.    canada.setCapital( "Ottawa" );
23.
24.    List world = new ArrayList();
25.    world.add( austria );
26.    world.add( canada  );
27.
28.    for( Iterator it = world.iterator(); it.hasNext(); )
29.    {
30.      Country country = (Country) it.next();
31.      System.out.println( "The capital of " + country.getName() + " is " +  country.getCapital() + "." );
32.    }     
33.  }
34. }

Why Groovy? What’s wrong with Ruby (JRuby), Python (Jython), or Smalltalk (Bistro)?

Why yet another scripting language?

  1. Groovy uses a Java-like syntax; easy to switch from Java to Groovy or from Groovy to Java
  2. Groovy builds on (reuses) the Java standard class library; Ruby, Python or Smalltalk include their own batteries (that is, standard libraries)
  3. Groovy compiles straight to standard Java bytecode; you can use groovyc as an alternative compiler to javac

What is Java?

  1. Java is a (systems) programming language (syntax).
  2. Java is a “standard” class library.
  3. Java is a bytecode runtime (virtual machine).

=> Groovy is Java

Application vs. Systems (Hard-Core) Programming / Groovy vs. Java

Groovy does not replace Java. Groovy complements Java and doesn’t compete head-on. Groovy is a dynamic (scripting) language for application development. Java is a programming language for (hard-core) systems development.

Groovy is Java

Groovy Standard Class Library Types == Java Standard Class Library Types

$ hello = "Hello"
$ hello.class

=> java.lang.String
$ list = [ "Vancouver", "Ottawa" ]
$ list.class

=> java.util.ArrayList
$ map = [ "Vancouver":"British Columbia", "Ottawa":"Ontario" ]
$ map.getClass()

=> java.util.LinkedHashMap
$ regex = ~/[a-zA-Z_0-9]+/
$ regex.class

=> java.util.regex.Pattern

Groovy is Java Continued: Annotations

@Entity
@Name("hotel")
class Hotel implements Serializable
{
     @Id @GeneratedValue
     Long id
 
     @Length(max=50) @NotNull
     String name
 
     @Length(max=100) @NotNull
     String address
 
     @Length(max=40) @NotNull
     String city
 
     @Length(min=2, max=10) @NotNull
     String state
 
     @Length(min=4, max=6) @NotNull
     String zip
 
     @Length(min=2, max=40) @NotNull
     String country
 
     @Column(precision=6, scale=2)
     BigDecimal price
 
     @Override
     String toString() {
         return "Hotel(${name}, ${address}, ${city}, ${zip})"
     }
}

(Source: What’s New in Groovy 1.5)

Groovy is Java Continued: Enums, Static Imports, Generics

class Talk {
     String title
}

class Speaker {
     String name
     List<Talk> talks = []
}

def me = new Speaker(
     name: 'Guillaume Laforge',
     talks: [
         new Talk(title: 'Groovy'),
         new Talk(title: 'Grails')
     ])
 
def talksField =  me.class.getDeclaredField('talks')
assert talksField.genericType.toString() == 'java.util.List<Talk>'

(Source: What’s New in Groovy 1.5)

Groovy Joint Compiler

Compiles Groovy and Java code; can handle any dependency cycles

Use the -j compiler switch to enable the joint compilation. Example:

Country.groovy:

class Country
{
   String name
   String capital

   String toString() { return "The capital of ${name} is ${capital}." }
}

World.java:

public class World
{
  public static void main( String args[] )
  {
    Country canada = new Country();
    
    canada.setName( "Canada" );
    canada.setCapital( "Ottawa" );

    System.out.println( canada.toString() );
  }
}

Let’s joint compile the Groovy and Java source.

$ groovyc -j Country.groovy World.java 

That’s it. Run it.

$ java World

=> The capital of Canada is Ottawa.

Voila.

Groovy Goodies Missing In Java

Groovy Lists: Built-In Syntax for Lists

Groovy

list = [1, 2, 3]

Java

List list = new LinkedList();
list.add( new Integer( 1 ) );
list.add( new Integer( 2 ) );
list.add( new Integer( 3 ) );

Groovy Maps: Built-In Syntax for Maps

Groovy

map = [ 'one' : 1, 'two' : 2, 'three': 3 ]
print map[ 'one' ]
print map.one // works too

Java

Map map = new HashMap();
map.put( "one", new Integer( 1 ) );
map.put( "two", new Integer( 2 ) );
map.put( "three", new Integer( 3 ) );

System.out.println( map.get( "one" ) );

More Groovy List and Map Examples

Empty List

list = []

Empty Map

map = [:]

Nested Lists

list = [1, 2, [4, 5], 'hello']

Negative (Reverse) Index

last = list[-1] 

Ranges

list = 1..100
sub  = list[1..20]
sub  = list[-5..-1]
sub  = list[1,5..10,15]

Operator Overloading

[1,2,3] + [4,5,6]    // returns [1,2,3,4,5,6]
[1,2,3,4] - [2,4,6]  // returns [1,3]
map[ 'one' ]

Many Helper Methods

[1,2,3,1,2,3].count(3)  // return 2
['one', 'two', 'three'].join( '+' )
[3,2,1].sort()

Groovy Loops: Higher-Level Loops Using Closures (Code Blocks)

Java

for( int i=1; i<=1000; i++ )
  System.out.println( "The lucky number is" + i + "today" );

Groovy

each

(1..1000).each { i -> println "The lucky number is ${i} today" }

or

(1..1000).each { println "The lucky number is ${it} today" }

upto

1.upto(1000) { println "The lucky number is ${it} today" }

step

1.step(1001,1) { println "The lucky number is ${it} today" }

times

1000.times { println "Groovy rocks big time!" }

What is a Closure (Code Block/Anonymous Function)?

Closures are a powerful way of passing around blocks of executable code (code blocks/functions). Think of a closure as an anonymous inner method/function that can accept parameters.

{ x -> println x }   // closure with parameter x
{ println it }       // closure with default parameter it
{ x, y -> x > y }    // closure with parameter x, y
{ println "Hello" }  // closure without parameters

squared_closure = { x -> x * x }   // store closure in a variable 

squared_closure.call( 2 ) // call closure like a method; returns 4
squared_closure( 2 )      // v2.0: call closure like a method 

Functions (Closures/Code Blocks) as First-Class Citizens:

Closures In Action: Groovy Collections vs. Plain Old Java Collections

Groovy

   1. def names = ["Ted", "Fred", "Jed", "Ned"]  
   2. println names  
   3.   
   4. def shortNames = names.findAll { it.size() <= 3 }  
   5. println shortNames.size()  
   6. shortNames.each { println it }  

Java

   1. import java.util.*;  
   2.   
   3. public class Erase {  
   4.     public static void main(String[] args) {  
   5.         List names = new ArrayList();  
   6.         names.add("Ted");  
   7.         names.add("Fred");  
   8.         names.add("Jed");  
   9.         names.add("Ned");  
  10.         System.out.println(names);  
  11.         Erase e = new Erase();  
  12.         List shortNames = e.filterLongerThan(names, 3);  
  13.         System.out.println (shortNames.size());  
  14.         for (Iterator i = shortNames.iterator(); i.hasNext(); ) {  
  15.             String s = (String) i.next();  
  16.             System.out.println(s);  
  17.         }  
  18.     }  
  19.   
  20.     public List filterLongerThan (List strings, int length) {  
  21.         List result = new ArrayList();  
  22.         for (Iterator i  = strings.iterator(); i.hasNext(); ) {  
  23.             String s = (String) i.next();  
  24.             if (s.length() < length+1) {  
  25.                 result.add(s);  
  26.             }  
  27.         }  
  28.         return result;  
  29.     }  
  30. }

Java Refactored

   1. import static java.lang.System.out;  
   2. import static java.util.Arrays.asList;  
   3. import java.util.ArrayList;  
   4. import java.util.List;  
   5. import org.apache.commons.collections.CollectionUtils;  
   6. import org.apache.commons.collections.Predicate;  
   7.   
   8. public class ListTests {  
   9.    public static void main( String[] args ) {  
  10.       List<String> names = asList( "Ted", "Fred", "Jed", "Ned" );  
  11.       out.println( names );  
  12.       List<String> shortNames = new ArrayList<String>();  
  13.       shortNames.addAll( names );  
  14.       CollectionUtils.filter( shortNames, new Predicate(){  
  15.          public boolean evaluate( Object input ) {  
  16.             return ((String) input).length() < 4;  
  17.          }  
  18.       } );  
  19.       out.println( shortNames.size() );  
  20.       for( String s : shortNames )  
  21.          out.println( s );  
  22.    }  
  23. }  

(Source: From Java to Groovy, Part 2: Closures and Built-In Syntax For Lists)

Higher-Level Loops and Functions For Maps And Lists

each

[5, 9, 1, 6].each { println it }

find

[5, 9, 1, 6].find { x -> x > 5 }    // returns 9

findAll

[5, 9, 1, 6].findAll { x -> x > 5 }  // returns [9, 6]

map

[5, 9, 1, 6].map { x -> x * 2 }   // returns [10, 18, 2, 12]

min / max

[5, 9, 1, 6].min()   // returns 1
[5, 9, 1, 6].max()   // returns 9

reverse

[1,2,3].reverse()   // returns [3,2,1]

Groovy JDK – Groovy Adds New Methods To Core Java Classes

Groovy adds new methods to the core Java classes to help productivity and polymorphism e.g. new closure methods: each, select, filter, collect

java.util.Collection

int count(java.lang.Object value)
void each(groovy.lang.Closure closure)
java.lang.Object find(groovy.lang.Closure closure)
java.util.List findAll(groovy.lang.Closure closure)
java.util.List getAt(java.lang.String property)
java.lang.String join(java.lang.String separator)
java.util.List map(groovy.lang.Closure closure)
java.lang.Object max(java.util.Collection self)
java.lang.Object max(java.util.Comparator comparator)
java.lang.Object max(groovy.lang.Closure closure)
java.lang.Object min(java.util.Collection self)
java.lang.Object min(java.util.Comparator comparator)
java.lang.Object min(groovy.lang.Closure closure)
java.util.List plus(java.util.Collection right)
java.util.List plus(java.lang.Object right)

and many more

java.io.File

void eachByte(groovy.lang.Closure closure)
void eachFile(groovy.lang.Closure closure)
void eachLine(groovy.lang.Closure closure)
void splitEachLine(java.lang.String sep, groovy.lang.Closure closure)
void withOutputStream(groovy.lang.Closure closure)
void withPrintWriter(groovy.lang.Closure closure)
void withReader(groovy.lang.Closure closure)
void withWriter(groovy.lang.Closure closure)

and many more

java.lang.Number

java.lang.Number minus(java.lang.Number right)
java.lang.Number multiply(java.lang.Number right)
java.lang.Number plus(java.lang.Number right)
java.lang.Number power(java.lang.Number exponent)
void step(java.lang.Number to, java.lang.Number stepNumber, groovy.lang.Closure closure)
void times(groovy.lang.Closure closure)
void upto(java.lang.Number to, groovy.lang.Closure closure)

and many more

java.lang.Object

boolean any(groovy.lang.Closure closure)
void each(groovy.lang.Closure closure)
boolean every(groovy.lang.Closure closure)
java.lang.Object find(groovy.lang.Closure closure)
java.lang.Object findAll(groovy.lang.Closure closure)
java.lang.Object invokeMethod(java.lang.String method, java.lang.Object arguments)
java.util.List map(groovy.lang.Closure closure)
void print(java.lang.Object value)

and many more

(Source: Groovy Class Library Reference)

Groovy Template Strings: Expressions In Strings

You can put Groovy expressions (including method calls) inside strings using the ${expression} syntax similar to Velocity or JSTL-EL.

Groovy

movie    = "Lost in Translation"
director = "Sofia Coppola"

println "${director} directed the movie ${movie}."

Java Flashback

String movie    = "Lost in Translation";
String director = "Sofia Coppola";

System.out.println( director + " directed the movie " + movie + "." );

Groovy

num = 4

println "${num} squared equals ${num*num}"

class Movie
{
  String title
  Person director
}

class Person
{
  String name
}

person = new Person( name:'Sofia Coppola' )
movie = new Movie( title:'Lost in Translation', director:person )

println "${movie.director.name} directed the movie ${movie.title}"

// ${movie.director.name} is the same as movie.getDirector().getName() in Java

Groovy Strings: Multi-Line/Here-Doc Strings And More

In Groovy you can start and end strings with single or double quotes and use the other kind of quote without escaping inside the string. Example:

println "Alice says, 'Groovy rocks.'"
println 'Alice says, "Groovy rocks."'

Multi-Line Strings/Here-Doc Strings

In Groovy you can create multi-line strings using the triple quote (""" or ''') syntax that lets you paste blocks of text into your source without any need for quotes. Example:

out = """
<html>
 <head>
   <title>Groovy Servlet</title>
 </head>
 <body>
  Hello, ${request.remoteHost}: ${session.counter}! ${new Date()} 
 </body>
</html>
"""

Groovy Path Expression Language

To avoid the risk of NullPointerException when walking object hierachies you can use the “?.”operator instead of “.”.

class Movie
{
  String title; Person director
}

class Person
{
  String name
}

movie = new Movie( title:'Leaving Las Vegas' )

// Doesn't throw NullPointerException
println "${movie.director?.name} directed the movie ${movie.title}"

// Throws NullPointerException
println "${movie.director.name} directed the movie ${movie.title}"

Not for Groovy strings only. You can use the Groovy path expression language (including closures) everywhere. Example:

if( customers.orders.any { it.amount > 1000 && it.product.type == "citrus" } ) 
{
  doSomething()
}

or

for( order in customers.findAll { it.country.code == "AT" }.orders ) 
{
  println "order ${order.id} has value ${order.value}"
} 

Groovy Markup (XML) Syntax

Alternative XML syntax similar to Groovy map and list syntax but for trees of anything. Example:

import groovy.xml.MarkupBuilder;

xml = new MarkupBuilder()

xml.xul() {
  menubar( id:"main" ) {
    menu( label:"Bookmarks" ) {
      menuitem( label:"Vancouver Groovy/Grails User Group", link:"http://groovyvan.com" )
      menuitem( label:"Gerald Bauer's Blog", link:"http://geraldbauer.wordpress.com" )
      menuitem( label:"Gerald Bauer's Tumblelog", link:"http://geraldbauer.tumblr.com" )
      menuitem( label:"Slide Show (S9)",  link:"http://slideshow.rubyforge.org" )
    }
  }
}   

println xml

generates the following XML markup:

<xul>
  <menubar id="main">
     <menu label="Bookmarks">
       <menuitem label="Vancouver Groovy/Grails User Group"  link="http://groovyvan.com" />
       <menuitem label="Gerald Bauer's Blog" link="http://geraldbauer.wordpress.com" />
       <menuitem label="Gerald Bauer's Tumblelog"    link="http://geraldbauer.tumblr.com" />
       <menuitem label="Slide Show (S9)"            link="http://slideshow.rubyforge.org" />
     </menu>
  </menubar>
</xul>

Note that you can mix and match Groovy markup with Groovy script (e.g. loops, method calls, variables, expressions, conditionals and so on).

Groovy SQL

Groovy Script using Groovy SQL and Groovy Markup

import groovy.xml.MarkupBuilder;
import groovy.sql.Sql
import java.sql.DriverManager

Class.forName( "org.hsqldb.jdbcDriver" )
con = DriverManager.getConnection( "jdbc:hsqldb:.", "sa", "" )
sql = new Sql( con )

xml = new MarkupBuilder()
xml.xul() {
  menubar( id:'main' ) {
    menu( label:'Bookmarks' )

    sql.queryEach( 'select title, link from bookmark' ) { row ->
         menuitem( label:"${row.title}", link:"${row.link}" )
    }
  }
}

println xml

Output

<xul>
  <menubar id="main">
     <menu label="Bookmarks">
       <menuitem label="Vancouver Groovy/Grails User Group"  link="http://groovyvan.com" />
       <menuitem label="Gerald Bauer's Blog" link="http://geraldbauer.wordpress.com" />
       <menuitem label="Gerald Bauer's Tumblelog"    link="http://geraldbauer.tumblr.com" />
       <menuitem label="Slide Show (S9)"            link="http://slideshow.rubyforge.org" />
     </menu>
  </menubar>
</xul>

Scripting Ant Using Groovy Markup (Gant)

Using Gant you can use Ant tasks and mix and match markup with scripts (e.g. you can pass on variables to Ant tasks and use Groovy code anywhere within the markup).

sourceDirectory = 'source'
buildDirectory = 'build'
includeTargets << gant.targets.Clean
cleanPattern << '**/*~'
cleanDirectory << buildDirectory
Ant.taskdef (  name : 'groovyc' , classname : 'org.codehaus.groovy.ant.Groovyc' )
target ( compile : 'Compile source to build directory.' ) {
   javac ( srcdir : sourceDirectory , destdir : buildDirectory , debug : 'on' )
   groovyc ( srcdir : sourceDirectory , destdir : buildDirectory )
}

(Source: Gant Project Site)

Building Swing Desktop Apps Using Groovy Markup

Groovy snippet:

 1. swing = new SwingBuilder()
 2. 
 3. frame = swing.frame( title:'Counter', size:[200,100]) {
 4.   panel(layout:new FlowLayout() ) {
 5.     display = textField( preferredSize:[200,30], horizontalAlignment:SwingConstants.CENTER )
 6.     button( text:"Inc", size:[65,70], actionPerformed:{ value++; setDisplay() } )
 7.     button( text:"Clear", size:[65,70], actionPerformed:{ value=0; setDisplay() } )
 8.     button( text:"Dec", size:[65,70], actionPerformed:{ value--; setDisplay() } )
 9.   }
10. }        

Java edition:

 1. frame = new JFrame( "Counter" );
 2. frame.getContentPane().setLayout( new FlowLayout() );
 3. frame.setSize( 200, 100 );
 4.
 5. display = new JTextField();
 6. display.setPreferredSize( new Dimension( 200, 300 );
 7. display.setHorizontalAlignment( SwingConstants.CENTER );
 8. frame.getContentPane().add( display );
 9.
10.  increment = new JButton( "Inc" );
11.  increment.setSize( 65, 70 );
12.  increment.addActionListener( new ActionListener() {
13.    public void actionPerformed( ActionEvent ev )
14.    {
15.       onIncrement();
16.    }
17.  } );
18.  frame.getContentPane().add( increment );
19.
20.  clear = new JButton( "Clear" );
21.  clear.setSize( 65, 70 );
22.  clear.addActionListener( new ActionListener() {
23.    public void actionPerformed( ActionEvent ev )
24.    {
25.      onClear();
26.    }
27.  } );
28.  frame.getContentPane().add( clear );
29.
30.  decrement = new JButton( "Dec" );
31.  decrement.setSize( 65, 70 );
32.  decrement.addActionListener( new ActionListener() {
33.    public void actionPerformed( ActionEvent ev )
34.    {
35.      onDecrement();
36.    }
37.  } );
38.  frame.getContentPane().add( decrement );

Groovy in Action

From Industry Giants…

…to Let’s Build a Blog in 5 Minutes

Groovy Heroes – G2One Inc. – The Groovy/Grails Startup

G2One Inc. – G2One.com

Founders include:

Similar to Sun (Java), SpringSource (Spring), RedHat (JBoss), IBM (Eclipse), etcetera

Groovy/Grails in Print – Books

Upcoming

Groovy/Grails Articles & Blogs

Groovy/Grails Experience (2GX) Conference

Talk Highlights

Next Groovy/Grails Experience (2GX) Conference in San Jose (California) in Fall 2008

Getting Started – Installing Groovy – 1-2-3 Steps

  1. Download and unzip Groovy archive from groovy.codehaus.org
  2. Set GROOVY_HOME environment variable
  3. Add %GROOVY_HOME%/bin to PATH

Hello Groovy

$ groovy --version

=> Groovy Version: 1.5.4 JVM: 10.0-b19
$ groovy -e "println 'Servus Groovy'"

=> Servus Groovy

Hello.groovy:

println "Servus Groovy"

$ groovy Hello.groovy

=> Servus Groovy

The End – Q&A – Thanks