Groooooovy Babe: Jazzing Up Plain Old Java

Scripting Power for Java - Do More With Less (Lines of Code)

Gerald Bauer (Chairman, CEO, CFO and CTO of Me, Myself & I, Inc.)
Java User Group (JUG) Austria Talk, March 2004


Table of Contents

Groooooovy Babe - Jazzing Up Plain Old Java

Who is this guy?


Agenda - The Road Ahead


What is Groovy?

Groovy Logo

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 smoth Java intergration: 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.


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

Why yet another scripting language?


One Language Can't Do It All: Beyond Hairballs and Spaghetti Code

Scripting on the Rise. The Death of General Purpose Languages and Monolithic Applications.

Prefer the single-purpose languages below to general-purpose languages such as Java, C# or Shark.


Scripting 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 scripting language. Java is a hard-core programming language (systems language).


First Impression - Servus Groovy Example

Java

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

Groovy

print 'Servus Groovy'

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

Java

import java.util.*;

public class HelloWorld
{
  public static void main( String args[] )
  {
     List country = new ArrayList();
     country.add( "Canada" );
     country.add( "Austria" );
     country.add( "Brazil" );

     Collections.sort( country );

     for( Iterator it = country.iterator(); it.hasNext() )
        System.out.println( "Hello " + it.next() );
  }
}

Groovy

country = [ 'Canada', 'Austria', 'Brazil' ]

country.sort

country.each { println "Hello ${it}" }

Ruby

country = [ 'Canada', 'Austria', 'Brazil' ]

country.sort

country.each { |country| puts "Hello #{country}" }

Third Impression - Groovy Beans vs Java Beans

Java

public class Country
{
   private String name;
   private String capital;

   public String getName()    { return name; }
   public String getCapital() { return capital; }

   public String setName( String name ) { this.name = name; }
   public String setCapital( String capital ) { this.capital = capital; }


   public static void main( String args[] )
   {
      Country austria = new Country();
      austria.setName( "Austria" );
      austria.setCapital( "Vienna" );

      Country canada = new Country();
      canada.setName( "Canada" );
      canada.setCapital( "Ottawa" );

      List world = new ArrayList();
      world.add( austria );
      world.add( canada  );

      for( Iterator it = world.iterator(); it.hasNext() )
      {
         Country country = it.next();
         System.out.println( "The capital of " + country.getName() + " is " +  country.getCapital() + "." );
      }     
   }
}

Groovy

class Country
{
   String name
   String capital
}

world = [new Country(name:'Austria', capital:'Vienna'),
         new Country(name:'Canada', capital:'Ottawa')]

world.each { country | println "The capital of ${country.name} is ${country.capital}." }

Ruby

class Country

  def initialize( name, capital )
    @name    = name
    @capital = capital
  end

  attr_reader( :name, :capital )
end

world = [ Country.new( 'Austria', 'Vienna' ), 
          Country.new( 'Canada', 'Ottawa' )]

world.each { | country | puts "The capital of #{country.name} is #{country.capital}." }

The Groovy Founding Fathers

Who is James Strachan?

Who is Bob McWhirter?


More Groovy Heros

Committers

Contributors

Source: http://groovy.codehaus.org/team-list.html


Groovy Goodies Missing In Java


Groovy Lists: Built-In Syntax for Lists

Java

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

Groovy

list = [1, 2, 3]

Groovy Maps: Built-In Syntax for Maps

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" ) );

Groovy

map = [ 'one' : 1, 'two' : 2, 'three': 3 ]
print map[ '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

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)?

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

  { x | println x }    // parameter x
  { println it }       // default parameter it
  { x, y | x > y }     // parameter x, y
  { println "Hello" }  // no parameters

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

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

Note, however that closures are more than anonymous inner methods. Groovy supports true closures where state can be passed into and out of closures. Any local variables in scope when the closure is created can be used and modified and any variables created within the closure are visible outside as local variables. No final keyword is required like with Java and annonymous inner classes. Example:

count = 0 

[1, 2, 3, 4].each { count += it; last = it } 

println( "the sum is ${count} and the last item was ${last}" )        

Note that count goes from the outer scope to the inner scope and back out again. The last variable goes from inside scope out.

Tip: A great way to learn more about closures is picking up a Ruby book such as the free Programming Ruby book by the Pragmatic Programmers. (Sorry there are no Groovy books yet on the market.)


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

Java (Using Standard Collection Library):

public List collectCounty( List data, String country )
{
  List result = new ArrayList(); 
  for(Iterator i = data.iterator(); i.hasNext();) 
  { 
    Address address = (Address) i.next(); 
    if( country.equals( address.getCountry()) ) 
      result.add( address ); 
  } 
  return result; 
}

List result = collectCountry( data, "Canada" );

Java (Using Groovy-ish Collection Library Mimicking Closures Using Anonymous Inner Single Method Interfaces):

Collection result = data.collect( new BooleanFilter() { 
  public void isMatch( Object candidate ) 
  { 
    return( (Address)candidate ).getCountry().equals( "Canada" ); 
  } 
});

Groovy (The Real Thing):

result = data.collect { address | "Canada" == address.country }  

Ruby:

result = data.collect { | address | "Canada" == address.country }

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


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: 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

In Groovy strings can span multiple lines. Example:

 blurb = "Groovy is a dynamic object-oriented language
   that combines the best from Smalltalk, Python and Ruby
   in an all-in-one package using a Java-like syntax."

 println blurb

Here-Doc Strings

You can create multi-line strings without quotes using what is called a "here-doc". After the three less-than characters (e.g. <<<) use your own delimiter (e.g. EOS) to enclose your text.

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


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

Built-in Syntax For Regular Expressions (Regex)

Groovy supports regular expressions with built-in syntax using the ~"..." expression. Plus Groovy supports the =~ (create Matcher) and ==~ (matches regex) operators. Example:

Java

Pattern pattern = Pattern.compile( "java" );

Groovy

pattern =~ "java"

Java

Matcher matcher = Pattern.compile( "java" ).matcher( "javajava" );
String answer = matcher.replaceAll( "kaffe" );

Groovy

matcher = "javajava" =~ "java"
answer  = matcher.replaceAll( "kaffe" )

Java

String answer = Pattern.compile( "java" ).matcher( "javajava" ).replaceFirst( "groovy" );

Groovy

answer = ("javajava" =~ "java").replaceFirst("groovy")

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:'Luxor XUL Project Page',  link:'http://luxor-xul.sourceforge.net' )
      menuitem( label:'Luxor XUL Tag Reference', link:'http://luxor-xul.sourceforge.net/luxorref.html' )
      menuitem( label:'Petra Plugin Central',    link:'http://petra.sourceforge.net' )
      menuitem( label:'XUL Alliance',            link:'http://xul.sourceforge.net' )
      menuitem( label:'The Richmond Post',       link:'http://xul.sourceforge.net/post' )
    }
  }
}   

println xml

generates the following XML markup:

<xul>
  <menubar id="MAIN">
     <menu label="Bookmarks">
       <menuitem label="Luxor XUL Project Page"  link="http://luxor-xul.sourceforge.net" />
       <menuitem label="Luxor XUL Tag Reference" link="http://luxor-xul.sourceforge.net/luxorref.html" />
       <menuitem label="Petra Plugin Central"    link="http://petra.sourceforge.net" />
       <menuitem label="XUL Alliance"            link="http://xul.sourceforge.net" />
       <menuitem label="The Richmond Post"       link="http://xul.sourceforge.net/post" />
     </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).


Scripting Ant Using Groovy Markup

Using the built-in AntBuilder 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).

ant = new AntBuilder() 

// lets just call one task
ant.echo("hello")
        
// here's an example of a block of Ant inside GroovyMarkup
ant.sequential {
  echo("inside sequential")
            
  myDir = "target/AntTest/"
            
  mkdir(dir:myDir) 
  copy(todir:myDir) {
    fileset(dir:"src/test") {
      include(name:"**/*.groovy")
    }
  }
            
  echo("done")
}
        
// now lets do some normal Groovy again
file = new File("target/AntTest/groovy/util/AntTest.groovy")
assert file.exists()

Building Swing UIs Using Groovy Markup

Plain Old Java snippet:

  frame = new JFrame( "Counter" );
  frame.getContentPane().setLayout( new FlowLayout() );
  frame.setSize( 200, 100 );

  display = new JTextField();
  display.setPreferredSize( new Dimension( 200, 300 );
  display.setHorizontalAlignment( SwingConstants.CENTER );
  frame.getContentPane().add( display );

  increment = new JButton( "Inc" );
  increment.setSize( 65, 70 );
  increment.addActionListener( new ActionListener() {
    public void actionPerformed( ActionEvent ev )
    {
       onIncrement();
    }
  } );
  frame.getContentPane().add( increment );

  clear = new JButton( "Clear" );
  clear.setSize( 65, 70 );
  clear.addActionListener( new ActionListener() {
    public void actionPerformed( ActionEvent ev )
    {
      onClear();
    }
  } );
  frame.getContentPane().add( clear );

  decrement = new JButton( "Dec" );
  decrement.setSize( 65, 70 );
  decrement.addActionListener( new ActionListener() {
    public void actionPerformed( ActionEvent ev )
    {
      onDecrement();
    }
  } );
  frame.getContentPane().add( decrement );
    

Groovy snippet:

swing = new SwingBuilder()

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

Tip: Use XML UI Language (XML) for your Swing UIs. If you use XUL you can reuse your Swing UIs no matter what language you use (e.g. Java, Jython (Python for Java), Groovy, etc.). For an example see the Luxor XUL Java Example Suite (Ramses), the Luxor XUL Python Example Suite, and the Luxor XUL Groovy Example Suite all reusing the same XUL file below.

<xul>
  <vbox id="COUNTER">
   <groupbox>
     <caption label="Counter"/>
     <textbox id="DISPLAY" 
           style="align: center; color: yellow; background: black; font: 24 bold monospace;" />
   </groupbox>
   <hbox>
     <button label="Dec (-)"  command="dec"   style="width: 90px" />
     <button label="Clear"    command="clear" style="width: 90px" />
     <button label="Inc (+)"  command="inc"   style="width: 90px" />
   </hbox>
  </vbox>
</xul>

Building Eclipse UIs Using Groovy Markup

Groovy snippet:

swt = new JFaceBuilder()
        
shell = swt.shell() {
         
  mainapp = applicationWindow() { 	
	         	
    menuManager( text:"File" ) {
      action ( text:"Very Nice", closure:{ println "Very Nice !!!" } )
      separator()
      action ( text:"Check me", checked:true, closure:{ println "I've been checked" } )
    }
	
    menuManager( text:"Edit" ) {
      action ( text:"Say Hi Statusbar", closure:{ mainapp.setStatus('Hello ...') } )
    }
	       
    fillLayout ( type:"vertical" )
	
    label( text:"A big red label", background:[204, 0, 0] ) 
    label( text:"I can barelly read this", foreground:[0,200,0] )  
    label( text:"It sure looks like the dutch flag", foreground:[0,0,150], background:[0, 0, 153] )
  }
} 

Groovy SQL

Output

<xul>
  <menubar id="MAIN">
    <menu label="Bookmarks">
       <menuitem label="Luxor XUL Project Page"  link="http://luxor-xul.sourceforge.net" />
       <menuitem label="Luxor XUL Tag Reference" link="http://luxor-xul.sourceforge.net/luxorref.html" />
       <menuitem label="The Memphis Sun"         link="http://luxor-xul.sourceforge.net/sun" />
       <menuitem label="Petra Plugin Central"    link="http://petra.sourceforge.net" />
       <menuitem label="XUL Alliance"            link="http://xul.sourceforge.net" />
       <menuitem label="The Richmond Post"       link="http://xul.sourceforge.net/post" />
    </menu>
  </menubar>
</xul>  

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

Groovy Java Interop: Static Typing Optional

Note, that Groovy also supports static typing (that is, declaring the type of variables before usage) in case you want to publish a method or interface for use back in Java land.

As long as you use Groovy just for 'scripts' you can keep your code completely dynamically typed and work like in Ruby or Python.


Embedding Groovy in Your App

You can evaluate any Groovy expression or script using GroovyShell (that is, the groovy.lang.GroovyShell class.) To pass variables in and out use the groovy.lang.Binding object. Example:

// call groovy expressions from Java code
Binding binding = new Binding();
binding.setVariable( "foo", new Integer(2) );

GroovyShell shell = new GroovyShell( binding );

Object value = shell.evaluate( "println 'Hello Groovy!'; x = 123; return foo * 10" );

assert value.equals(new Integer(20));
assert binding.getVariable("x").equals( new Integer(123) );

Loading and Running Groovy Scripts inside Java on the Fly

You can load Groovy classes dynamically into a Java program and execute them on the fly using the GroovyClassLoader. Example:

GroovyClassLoader loader = new GroovyClassLoader();
Class groovyClass = loader.parseClass( new File("src/test/groovy/script/HelloWorld.groovy") );

// lets call some method on an instance
GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
Object[] args = {};
groovyObject.invokeMethod( "run", args );

Compiling Groovy Scripts Using groovyc

groovyc lets you compile Groovy scripts ahead-of-time to Java bytecode (that is, .class files). Note, that every Groovy class becomes a "normal" Java class that you can use inside your Java code. The only difference between a Groovy generated Java class and a plain old Java class is that a Groovy generated Java class supports the groovy.lang.GroovyObject interface.

Usage Example

Compile all Groovy scripts in current folder to Java bytecode

groovyc *.groovy

Compile the Groovy script Graph.groovy to Java bytecode (e.g. Graph.class)

groovyc Graph.groovy

Compiler Options

Option Description
--classpath path Specify where to find user class files
-d directory Specify where to place generated class files
--strict Turn on strict type safety
--version Print the version
--help Print a synopsis of standard options

Runtime Dependencies

Compiled Groovy scripts require two runtime libraries, that is, the Groovy Runtime Library and the ObjectWeb ASM Bytecode Library e.g. groovy-1.0-beta-3.jar (~400k) and asm-1.4.1.jar (~30k)


Compiling Groovy Scripts Using Ant or Maven

You can also compile Groovy scripts to Java bytecode using the <groovyc> Ant task.

Ant Task Paramter

Attribute Description Required
sourcedir Specify where to find Groovy script files Yes
destdir Specify where to place generated class files Yes
classpath Specify where to find user class files No

Example

<taskdef name="groovyc" classname="org.codehaus.groovy.ant.Groovyc" 
         classpathref="test.classpath" />

<groovyc destdir="${basedir}/target/test-classes" 
         srcdir="${basedir}/target/test-classes" listfiles="true">
  <classpath refid="test.classpath" />
</groovyc>

More Groovy Goodies in the Pipeline


Alternative Scripting Languages for the Java Runtime

Jython (Python for Java)
http://www.jython.org | http://sourceforge.net/projects/jython
Jython is a 100 % Java version of the Python scripting language that allows you to compile Python scripts to Java byte code that runs on any Java Virtual Machine. Jython offers seamless and smoth Java intergration: from Python you can access all Java libraries, you can build applets or Java beans, you can derive from Java classes in Python and vice versa. Like Python, and unlike Java, you can use Jython interactively: just type in some Jython code at the prompt and see the story unfold immediately; licensed under an Apache-style license; headed by Finn Bock

Java Lite/Dynamic Java - BeanShell (bsh)
http://www.beanshell.org | http://sourceforge.net/projects/beanshell
BeanShell (bsh) is a free, open-source, small (~175k) scripting interpreter in 100 % Java that runs standard Java statements and expressions and also sports a dynamically typed, casting optional Java lite syntax; licensed under GNU Library GPL (LGPL); headed by Patrick Niemeyer.

Tcl - Jacl (Java Command Language)
http://tcljava.sourceforge.net | http://sourceforge.net/projects/tcljava | http://www.tcl.tk/software/java
Jacl is a free, open-source Tcl 8.x scripting interpreter in 100 % Java initially created by Sun Labs in 1998 and now headed Mo DeJong; licensed under a BSD license; Jon Ousterhout created Tcl in the late 80's as an embeddable command language for interactive Unix tools.

JavacScript - Rhino
http://www.mozilla.org/rhino
Rhino is a free, open-source Mozilla-licensed Javascript engine in 100 % Java. Netscape started work on Rhino in Fall 1997 for the now defunct "Javagator".

Ruby - JRuby
http://jruby.sourceforge.net | http://sourceforge.net/projects/jruby
JRuby is a free, open-source Ruby interpreter in 100 % Java that you can easily add to your app to script any Java class.

Smalltalk - Bistro
http://bistro.sourceforge.net | http://sourceforge.net/projects/bistro
Bistro is a free, open-source variant of Smalltalk in 100 % Java than runs on any Java Virtual Machine. Bistro mixes the best of Smalltalk and Java.

Lisp/Scheme - Kawa
http://www.gnu.org/software/kawa
Scheme interpreter in 100 % Java; licensed under the GNU GPL; headed by Per Bothner; (Scheme is a modern variant of Lisp.)

And Many More (Lua, Basic, and so on and on). See Robert Tolksdorf's list of programming languages for the Java Virtual Machine for more.

Source: http://viva.sourceforge.net/lang.html


Viva! Scripting Language of the Year 2003 Award

Source: http://viva.sourceforge.net/republic/2004/01


Scripting Languages Comparison Chart

Feature Groovy Python Tcl Perl Java Script Ruby Visual Basic
Speed of use Rapid development Yes Yes Yes Yes Yes Yes Yes
Flexible, rapid evolution Yes Yes Yes Yes Yes Yes Yes
Great regular expressions Yes Yes Yes Yes Yes
Breadth of functionality Easily extensible Yes Yes Yes Yes Yes
Embeddable Yes Yes Yes Yes
Easy UIs Yes Yes Yes Yes Yes
Internet and Web-enabled Yes Yes Yes Yes Yes Yes Yes
Enterprise usage Cross platform Yes Yes Yes Yes Yes Yes
Internationalization support Yes Yes Yes Yes Yes
Thread safe Yes Yes Yes Yes
Database access Yes Yes Yes Yes Yes Yes Yes

Source: http://www.tcl.tk/advocacy


Groovy Links, Links, Links

Official Groovy Site
http://groovy.codehaus.org

Groovy Library Reference (Groovy JDK API)
http://groovy.codehaus.org/groovy-jdk.html

Groovy Wiki Wiki
http://wiki.codehaus.org/groovy

Articles, Talk Slides

Groovy - Making Java More Funky
James Strachan @ Codehaus One Summit, August 2003, Amsterdam
http://codehaus.org/~jstrachan/Groovy/html/groovy.html

Groovy - Scripting for Java
Mark Volkmann (Object Computing Inc.), Java News Brief (JNB), February 2004
http://www.ociweb.com/jnb/jnbFeb2004.html

Mailinglists

groovy-user Mailinglist
http://lists.codehaus.org/mailman/listinfo/groovy-user | http://news.gmane.org/gmane.comp.lang.groovy.user

News

James Strachan's Blog (Groovy Creator)
http://radio.weblogs.com/0112098


Ruby Links, Links, Links

Official Ruby Site
http://www.ruby-lang.org
Ruby - The Programmer's Best Friend

"One-Click" Ruby Installer for Windows
http://rubyinstaller.sourceforge.net
Self-contained "one-click" installer that comprises the Ruby language itself, dozens of popular extensions and packages, a syntax-highlighting editor and execution environment, and a Windows help file that contains the full text of the book, "Programming Ruby: The Pragmatic Programmer's Guide".

Books

Programming Ruby: A Pragmatic Programmer's Guide by David Thomas and Andrew Hunt, 608 pages, Addison-Wesley, ISBN: 0201710897, (December 2000); Free Online Version

and many more


Bonus Slide: Python (Jython) Links, Links, Links

Please see my Java User Group (JUG) Austria talk slides titled "Python and Jelly: Scripting Power for Java and XML: Do More With Less (Lines of Code)" online @ http://luxor-xul.sourceforge.net/talk/jug-feb-2003/slides.html


Scripting: Higher Level Programming for the 21st Century

Paper by John K. Ousterhout, Father of Tcl/Tk, published in IEEE Computer in March 1998

Scripting Is On The Rise; Different Tools for Different Tasks

Scripting languages and system programming languages are complementary, and most major computing platforms since the 60's have provided both kinds of languages. The languages are typically used together in component frameworks, where components are created with system programming languages and glued together with scripting languages. However, serveral recent trends, such as faster machines, better scripting languages, the increasing importance of graphical user interfaces and component architectures, and the growth of the Internet, have greatly increased the applicability of scripting languages.

Full story at http://home.pacbell.net/ouster/scripting.html


That's it - The Future Just Happened

Visit http://viva.sourceforge.net for more info