Groovy, Java's new scripting language.When some Java developers hear about Groovy groov·y adj. groov·i·er, groov·i·est Slang Very pleasing; wonderful. groov i·ness n. , their first reaction
often is, as mine was, "Oh, no, not another scripting language A high-level programming, or command, language that is interpreted (translated on the fly) rather than compiled ahead of time. A scripting, or script, language may be a general-purpose programming language or it may be limited to specific functions used to augment the running of an for
Java." We already have, after all, JavaScript and Rhino, Jython,
Jelly, BeanShell, JRuby, Tcl/Java, Sleep, ObjectScript, Pnuts,
Judoscript, the Bean Scripting Framework The Bean Scripting Framework is a method of allowing the use of scripting in Java code. It provides a set of Java classes which provides support within Java applications for scripting languages, and also allows access to Java objects and methods. (BSF BSF B lymphocyte stimulatory factor. )--which gives access to
Perl, TK/Tcl, and more--and many others. But other developers have been
hoping for a scripting language with the power of Perl, Python Python, in Greek mythologyPython, in Greek mythology, a huge serpent. In some myths the infant Apollo slew Python at the oracle of Gaea in Delphi; in others Apollo killed the serpent in order to claim the oracle for himself. , or Ruby but without having to re-learn everything from the ground up. Whichever camp you're in, I hope to show you enough of Groovy in this article that you will be interested to try it and judge for yourself. Why Groovy? Why would Bob McWhirter and James Strachan James Strachan was president of the Montreal Maroons when they won their first Stanley Cup championship in 1926. create a new scripting language? Why would they call it Groovy? More importantly, what features would enable Groovy to succeed when others are already entrenched en·trench also in·trench v. en·trenched, en·trench·ing, en·trench·es v.tr. 1. To provide with a trench, especially for the purpose of fortifying or defending. 2. ? Let's answer the third question with a look at Groovy's features. When scripting languages that started elsewhere come to Java, they tend to bring a lot of their own API (Application Programming Interface) A language and message format used by an application program to communicate with the operating system or some other control program such as a database management system (DBMS) or communications protocol. with them rather than using the "standard" (to us) Java API. Groovy is not guilty here--it provides very little special-purpose API; the entirety of the standard Java API is given to you in Groovy as it is in Java, and any third-party Java can be made available just by putting it in your CLASSPATH. Quoting the Groovy FAQ (Frequently Asked Questions) A group of commonly asked questions about a subject along with the answers. Vendors often display them on their Web sites for use as troubleshooting guidelines. :
Think of Groovy as a Ruby--or Python-like language that is
tightly integrated with the Java platform (as opposed to the
Unix/Posix command shell and C-libraries), allowing you the same
powerful and concise coding syntax as Ruby or Python, but
allowing you to stay on the JVM and protect your investment in
J2SE, J2EE, and all the plethora of great useful Java code out
there without any adapter layers or parallel API sets ...
Foreign scripting languages tend to have their own special syntax, based on what the original developers liked. Groovy is peachy peach·y adj. peach·i·er, peach·i·est 1. Resembling a peach, especially in color or texture. 2. Informal Splendid; fine. here, too, because its syntax is based on Java's, with just a spoonful of syntactic sugar Certain coding rules in a programming language that make it easier for a person to write a program. For example, in Perl, the double dot operator is used to create multiple values. Writing ('A' .. 'Z') declares a range of values from "A" to "Z. to help the medicine go down. For example, instead of having to write: value = object.getItemCount(); you can just write: value = object.itemCount In other words Adv. 1. in other words - otherwise stated; "in other words, we are broke" put differently , objects in Groovy are treated as JavaBeans, and setters/getters result in accessible properties. Because Groovy is generally much less restrictive than Java about declarations, most variables in Java can be assigned without declaring them, although at present you can't use the += operator on something that doesn't have a value. In fact, you can create bean classes in Groovy without having to write accessors, as shown in the person.groovy example below. Groovy statements don't need to have a class statement and named methods if they are self-contained; but if you want to define one or more classes you can, and classes can have method definitions.
Example 1. person.groovy
class Person {
firstName
lastName
address1
city
province
postcode
}
p = new Person(firstName:'Ian', lastName:'Darwin', province:'Ontario')
println "Hello ${p.firstName} ${p.lastName}"
Another bit of syntactic sugar is that semicolons are optional at the end of statements. You may, as I do, put them in out of habit and because it's easier to be consistent. But the Groovy language isn't Java, and if you want to leave off your semicolons, you can. And before you start denigrating den·i·grate tr.v. den·i·grat·ed, den·i·grat·ing, den·i·grates 1. To attack the character or reputation of; speak ill of; defame. 2. "syntactic sugar," remember that J2SE (Java 2 platform, Standard Edition) See Java 2. J2SE - Java 2 Platform, Standard Edition 1.5 ("Java 5") provides auto-boxing and auto-unboxing, which automatically converts between primitives like ints and, whenever needed, their object-wrapper equivalents (like Integer integer: see number; number theory ). (Chapter 8 of my book, Java Cookbook (programming) cookbook - (From amateur electronics and radio) A book of small code segments that the reader can use to do various magic things in programs. One current example is the "PostScript Language Tutorial and Cookbook" by Adobe Systems, Inc (Addison-Wesley, ISBN , 2nd Edition, covers this and other new-in-1.5 features such as Generics; you can download this chapter from the book's catalog page.) A third problem with some scripting languages has been performance, though this has become less of an issue as computers get faster. Somebody once wrote that software expands to use up all available increases in computing resources, and that doesn't seem far off the mark when you look at modern commercial operating systems Operating systems can be categorized by technology, ownership, licensing, working state, usage, and by many other characteristics. In practice, many of these groupings may overlap. and applications. Groovy wins here, too, because Groovy scripts can be compiled into class files. These files are indistinguishable from those produced by javac or an IDE, and can therefore take advantage of speed improvements in, for example, Sun's HotSpot optimizing-Just-In-Time JVM See Java Virtual Machine. JVM - Java Virtual Machine . Well, indistinguishable syntactically; they are well-formed Java bytecode Java bytecode is the form of instructions that the Java virtual machine executes. Each bytecode instruction is one byte in length (hence the name), thus the number of bytecodes is limited to 256. Not all 256 possible bytecode values are used. files. That does not mean that you can compile any Groovy script into a standalone Java program--the Groovy runtime is required on your classpath, both to compile the Java code that uses Groovy, and to find the Java classes of the Groovy runtime. I'll give an example later. Finally, some scripting languages tend to have ambiguous documentation, or multiple implementations (Jython versus Python, for example). Groovy again wins here--its language has a Java Standards Request, or JSR JSR Java Specification Request JSR J Sargeant Reynolds Community College (Virginia) JSR Journal of Sedimentary Research JSR Jump to Subroutine (6502 processor instruction) 241, that includes a precise Groovy Language Specification (GLS GLS - Guy Lewis Steele, Jr. ). The specification co-lead and main author of the GLS is Richard Monson-Haefel, well known as the author of the O'Reilly book Enterprise JavaBeans See EJB. (specification, business, programming) Enterprise JavaBeans - (EJB) A server-side component architecture for writing reusable business logic and portable enterprise applications. EJB is the basis of Sun's Java 2 Platform, Enterprise Edition (J2EE). and member of the EJB (Enterprise JavaBeans) A software component in Sun's J2EE platform, which provides a pure Java environment for developing and running distributed applications. EJBs are written as software modules that contain the business logic of the application. 2 JSR experts group. Richard is also the only person I know who wrote an entire EJB server for fun, and gave it away as open source. (He's also the original author of OpenEJB, which has been incorporated into Apple's WebObjects and Apache Geronimo The Geronimo project is a free software application server developed by the Apache Software Foundation and distributed under the Apache license. Geronimo is currently compatible with the Java Enterprise Edition (Java EE) 5.0 specification. .) Why Use Groovy? So, it's groovy that Groovy doesn't suffer from the problems above, but what is it actually good for? Well, any kind of scripting, really. People are starting to use it for prototyping; that is, get an algorithm working in Groovy, then convert it to Java. But often you can just write something in Groovy and keep it as a Groovy script. Just to give you one example, see the fixid.groovy example below, a script I wrote to ensure that all of the Java files in a project have a CVS (1) (Concurrent Versions System) A version control system for Unix that was initially developed as a series of shell scripts in the mid-1980s. CVS maintains the changes between one source code version and another and stores all the changes in one file. ID string.
Example 2. fixid.groovy
# Make sure all the Java files in a collection have a CVS ID String.
# Don't apply to all files because it may damage binary files.
new java.io.File(".").eachFileRecurse({file | if
(file.name.endsWith(".java")) {
old = file.getText ()
if (!old.contains("$Id")) {
println "Fixing file ${file.name}"
out = file.newPrintWriter()
out.println("// Next line added by fixid script;
should move into doc comment")
out.println("// $I"+"d$") // + to hide from CVS
out.print(old)
out.close()
}
}
})
Getting Started The only good way to learn a language (even a scripting variant of a language you know) is to download it "Download It" is Clea's debut single. It was released in the UK on September 22, 2003 and missed the top 20 charting at #21. The single had average promotion, being performed in shows like Top of the Pops. and start applying it. (It's also a good idea to review the installation notes page.) And, if you don't want to type in my code examples, you can download them here. You need JDK (Java Development Kit) A Java software development environment from Sun. It includes the JVM, compiler, debugger and other tools for developing Java applets and applications. Each new version of the JDK adds features and enhancements to the language. 1.4 or later; Groovy will not run on 1.3. When you unpack See pack. the archive, you should wind up with these subdirectories: * bin: Shell scripts/batch files to run it * docs: Documentation * lib: The .jar files: groovy and asm, plus a couple of dozen support .jars To use Groovy, all you need to do is set GROOVY_HOME (and JAVA_HOME, but you probably have that set already). And you probably want to put GROOVY_HOME/bin onto your program path. For example, on my Mac with the Unix Korn Shell A command line processor for Unix that adds extensions to the Bourne shell. It includes many C shell functions, but is supported by more versions of Unix than C shell. See Bourne shell, bash shell, C shell and Unix. Korn Shell - (ksh) A command interpreter for Unix. , I have lines like these in my .profile: export JAVA_HOME=/Library/Java/Home export GROOVY_HOME=/home/ian/groovy PATH=$PATH: $GROOVY_HOME/bin There are several ways to invoke Groovy interactively. The groovysh terminal-based interpreter and the groovyConsole GUI (Graphical User Interface) A graphics-based user interface that incorporates movable windows, icons and a mouse. The ability to resize application windows and change style and size of fonts are the significant advantages of a GUI vs. a character-based interface. interpreter let you try your hand at composing Groovy interactively. Using the present version (Beta 0.6.1) of groovysh consists of typing one or more Groovy statements, then typing "go" or "execute" to run them (though this is labelled as a "temporary command"). Here's an example of groovysh in action:
Example 3. groovysh
ian: 61$ groovysh
Lets get Groovy!
================
Version: 1.0-beta-6 JVM: 1.4.2-38
Type 'exit' to terminate the shell
Type 'help' for command help
1> meaning = 42
2> println "Hello. Did you know that all it means is ${meaning}?"
3> go
Hello. Did you know that all it means is 42?
1> exit
ian: 62$
Using the groovyConsole consists of typing Groovy statements in the bottom panel, then invoking the Action [right arrow] Run menu item and looking in the top panel for messages and the invoking console for standard output (Ctrl-R is the keyboard shortcut
A keyboard shortcut (or accelerator key, shortcut key, hot key, key binding, keybinding, for Run). groovyConsole has the advantage that you can save a script file script file see batch file. from its File menu. Here's an example of As well, the groovy command runs a set of Groovy statements entered on the command line (with -e), or stored in a text file whose name is given on the command.
groovy -e 'System.in.readLines () .each { println it }'
This makes a simple "line count" program, for example:
ian$ls | groovy -e 'c=0; System.in.readLines ().each { ++c };println c'
6
ian$
At least on Unix/Linux/BSD/Mac OS X, you need to put single quotes around the entire command to protect all "metacharacters" in it. Which you use is a matter of choice. There are also Groovy plugins for popular IDEs, including Eclipse, IntelliJ, IDea (but its page is blank), and even vim. There is not yet support for Emacs or NetBeans, as far as I can tell. But given Groovy's similarity to Java, both of these should soon follow. And, once the JSR is a bit further along, I'd expect to see the commercial IDEs catching up. Groovy Is Not Java Groovy provides some syntax extensions beyond standard Java. One of the most interesting is what are called closures. This term has been overloaded in a lot of places in computer science, but for now just think of Groovy closures as being similar to anonymous inner classes. One difference is that variables can be passed in or out; Groovy closures do not constitute a "lexical scope (programming) lexical scope - (Or "static scope") When the scope of an identifier is fixed at compile time to some region in the source code containing the identifier's declaration. " the way an inner class does. The example below, closures.groovy, shows how to break a String into a List and print it one word per line, both the "long way" and using closures.
Example 4. closures.groovy
# without closures
x = "When in the course of human events ...".tokenize ()
for (val in x) println val
# with closures
"When in the course of human events ...".tokenize () .each { val |
println val }
# with closures, default parameter name
"When in the course of human events ...".tokenize () .each
{ println it }
The closure code is used to print each value of the list. In the first version, a parameter, val, is declared (before the |), and used in the body. In the second version, I use Groovy's default parameter name it (presumably pre·sum·a·ble adj. That can be presumed or taken for granted; reasonable as a supposition: presumable causes of the disaster. short for "item"). Another interesting syntax enhancement is the use of variable substitution within strings. Almost any String assignment can contain the pattern $ {variablename}, and the value of the named variable will be interpolated interpolated /in·ter·po·lat·ed/ (in-ter´po-la?ted) inserted between other elements or parts. into the String. This is a much more convenient form than Java's extensive use of the + operator for string concatenation. This can be used in printing, as in this hello.groovy example:
Example 5. hello.groovy and date.groovy
i = 42
println "Hello ${i}"
This prints "Hello 42". The interpolated value can be a property, as shown in date.groovy:
i = new java.util.Date ();
println "Today is day ${i.day} of month ${i.month}"
I said that Groovy doesn't bring a lot of new API New API (also referred to as NAPI) is an interface to use interrupt mitigation techniques for networking devices in the Linux kernel. Such an approach is intended to reduce the overhead of packet receiving. . But it does offer a lot of convenience methods added onto the standard API. For example, the Groovy version of String adds the tokenize () method used in the closure.groovy example above. The file docs/groovy-jdk.html in the Groovy distribution lists all of the methods added to the JDK classes; it's quite an extensive list, and adds up to a great deal of time saved when using Groovy compared to using "raw Java." As another example, Groovy's java.io.File class has a newReader method that returns a BufferedReader (and newPrintWriter (), which returns a PrintWriter). java.io.File also has eachLine, which opens the file and reads each line for you; now that's high-level! The example below is wc.groovy, my implementation of wc, a traditional Unix tool that counts the lines, words, and characters in a text file:
Example 6. wc.groovy
# simple implementation of Unix "wc" in groovy.
# could simplify with File.splitEachLine () but this way gets "chars"
right.
filename=args [0]
chars=0; lines=0; words=0;
new java.io.File (filename) .eachLine {
chars+=it.length () + 1
words+=it.tokenize () .size ();
lines++;
}
println "\t${lines}\t${words}\t${chars}\t${filename}"
Running the script produces output that is close to the original:
Example 7. wc.groovy versus the original
ian: 136$ wc test.txt
2 25 130 test.txt
ian: 137$ groovy wc.groovy test.txt
2 25 130 test.txt
ian:138
Groovy also adds several convenience methods for lists and maps; some of these are shown in the lists.groovy example below:
Example 8. lists.groovy
# List operations
list = ["ian", "brian", "brain"]
println list;
println "Maximum value: ${list.max()}"
# inject is like an iterator with carryover of last value
list.inject ("foo", { val, elem|println "${val} -- ${elem}"; return elem
})
# findAll returns all the elements for which the closure returns true.
println "findAll: "+list.findAll ({it.contains ("ian")})
# Ruby-style ranges, +- operators, etc.
validCardYears = 2004..2008
validCardYears.each {println "Valid year: ${it}"}
lastValidCardYear = validCardYears [-1]
println "Last valid year is currently ${lastValidCardYear}"
Running this catch-all script produces the following output. groovy src/lists.groovy [ian, brian, brain] Maximum value: ian foo -- ian ian -- brian brian -- brain findAll: [ian, brian] Valid year: 2004 Valid year: 2005 Valid year: 2006 Valid year: 2007 Valid year: 2008 Last valid year is currently 2008 Finally, just to prove it can be done, I back-ported wc.groovy into Java; the WC.java example gives the right answer, but has roughly twice the amount of code.
Example 9. WC.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;
/** simple implementation of unix "wc" in Java. */
public class WC {
public static void main (String[] args) throws IOException {
int chars=0, lines=0, words=0;
String filename=args [0];
BufferedReader r = new BufferedReader (new FileReader
(filename));
String it;
while ((it = r.readLine ()) != null) {
chars+=it.length () + 1;
words+=new StringTokenizer (it) .countTokens
();
lines++;
}
System.out.println ("\t" + lines + "\t" + words +
"\t" + chars + "\t" + filename);
}
}
XML XML in full Extensible Markup Language. Markup language developed to be a simplified and more structural version of SGML. It incorporates features of HTML (e.g., hypertext linking), but is designed to overcome some of HTML's limitations. , Swing, Builder, and All That Groovy includes a tree-based markup (text) markup - In computerised document preparation, a method of adding information to the text indicating the logical components of a document, or instructions for layout of the text on the page or other information which can be interpreted by some automatic system. generator called GroovyMarkup that can be subclassed to make a variety of tree-based object representations, including XML markup, HTML markup, SAX event firing, and even Swing user interfaces! The example below, swingbuilder.groovy, shows a user interface with a variety of labels and text fields built from a list, a pop-up "About" box, and two ways of exiting: a push button or just closing the main window (since defaultCloseOperation is set to EXIT_ON_CLOSE).
Example 10. swingbuilder.groovy
import groovy.swing.SwingBuilder;
theMap = ["color":"green", "object":"pencil", "location":"home"];
// create a JFrame with a label and text field for each key in the Map
swing = new SwingBuilder ();
frame = swing.frame (title: 'A Groovy Swing', location: [240, 240],
defaultCloseOperation:javax.swing.WindowConstants.
EXIT_ON_CLOSE)
{
panel () {
for (entry in theMap) {
label (text:entry.key)
textField(text:entry.value)
}
button (text: 'About', actionPerformed: {
pane = swing.optionPane (message:
'SwingBuilder Demo v0.0')
dialog = pane.createDialog (null, 'About')
dialog.show()
})
button (text: 'Quit', actionPerformed: { System.exit
(0) });
}
}
frame.pack ();
frame.show ();
There are no actions yet for the text fields, so changing them doesn't actually do anything. A more elaborate Swing demo, and other demos, can be found at the Groovy web site. Contact the editor at e-patterson@bt.connect.com |
|
||||||||||||||||||||

i·ness n.
Printer friendly
Cite/link
Email
Feedback
Reader Opinion