blob: cf4e2c12ec26b529c3f5b33fb8e663e825be4f65 [file] [log] [blame]
== Overview of Groovy 1.6
As we shall see in this article, the main highlights of this Groovy 1.6
release are:
* *Greater compile-time and runtime performance improvements*
* Multiple assignments
* Optional return in `if`/`else` and `try`/`catch` blocks
* Java 5 annotation definition
* *AST transformationsand all the provided transformation annotations
like`@Singleton``@Lazy``@Immutable``@Delegate` and friends
* The Grape module and dependency system and its `@Grab` transformation
* Various Swing builder improvements, thanks to the Swing
link:http://griffon-framework.org/[Griffon] team, as well as several Swing
console improvements
* The integration of *JMX builder*
* Various *metaprogramming improvements*, like the EMC DSL, per-instance
metaclasses even for POJOs, and runtime mixins
* *JSR-223scripting engine built-in
* Out-of-the-box *OSGi readiness*
All those improvements and new features serve one goal: *helping
developers be more productive and more agile*, by:
* Focusing more on the task at hand than on boiler-plate technical code
* Leveraging existing Enterprise APIs rather than reinventing the wheel
* Improving the overal performance and quality of the language
* Enabling developers to customize the language at will to derive their
own Domain-Specific Languages
But beyond all these important aspects, *Groovy is not just a language,
its a whole ecosystem*.
The improvements in Groovys generated bytecode information helps
capable tools coverage
like link:http://cobertura.github.io/cobertura/[Cobertura] and
its Groovy support, or pave the way for new utilities
like link:http://codenarc.sourceforge.net/[CodeNarc] for static code analysis
for Groovy.
The malleability of the syntax of the language and its metaprogramming
capabilities give birth to advanced testing tools such as
the link:http://easyb.org/[Easyb] Behavior-Driven-Development project,
the link:http://code.google.com/p/gmock/[GMock] mocking library or
the link:http://code.google.com/p/spock/[Spock] testing and specification
framework.
Again, Groovys flexibility and expressivity and its scripting
capabilities open the doors to advanced build scripting or
infrastructure systems for your continuous integration practices and
project build solutions, such
as link:https://gant.github.io/[Gant] and link:http://www.gradle.org/[Gradle].
At the tooling level, Groovy also progresses, for instance with
its `groovydoc` Ant task to let you generate proper JavaDoc covering,
documenting and interlinking both your Groovy and Java source files for
your Groovy/Java mixed projects.
And at the same time, IDE makers improve their support for Groovy, by
giving users powerful weapons such as cross-language code refactoring,
profound understanding of dynamic language idioms, code completion, and
more, to make developers productive when using Groovy in their projects.
Now, armed with this knowledge of the Groovy world, its time to dive
into the novelties of Groovy 1.6!
[[Groovy16releasenotes-Performanceimprovements]]
== Performance improvements
A lot of care has been taken to improve both the compile-time and
runtime performance of Groovy, compared to previous releases.
The *compiler is 3 to 5 times fasterthan in previous releases. This
improvement has also been backported in the 1.5.x branch, so that both
the old maintenance branch and the current stable branch benefit from
this work. Thanks to class lookup caches, the bigger the project, the
faster the compilation will be.
However, the most noticeable changes will be in the general runtime
performance improvements of Groovy. We used several benchmarks from
the link:http://shootout.alioth.debian.org/[Great Language Shootout] to
measure our progress. On those we selected, compared to the old Groovy
1.5.x line, the*performance improvements ranged from 150% to 460%*.
Micro-benchmarks obviously rarely reflect the kind of code you have in
your own projects, but the overal performance of your projects should
improve significantly.
[[Groovy16releasenotes-Multipleassignments]]
== Multiple assignments
In Groovy 1.6, there is only one syntax addition for being able to
define and assign several variables at once:
[source,groovy]
-------------------
def (a, b) = [1, 2]
assert a == 1
assert b == 2
-------------------
A more meaninful example may be methods returning longitute and latitude
coordinates. If these coordinates are represented as a list of two
elements, you can easily get back to each element as follows:
[source,groovy]
---------------------------------------------------------------------
def geocode(String location) {
// implementation returns [48.824068, 2.531733] for Paris, France
}
def (lat, long) = geocode("Paris, France")
assert lat == 48.824068
assert long == 2.531733
---------------------------------------------------------------------
And you can also define the types of the variables in one shot as
follows:
[source,groovy]
-------------------------------------
def (int i, String s) = [1, 'Groovy']
assert i == 1
assert s == 'Groovy'
-------------------------------------
For the assignment (with prior definition of the variables), just omit
the `def` keyword:
[source,groovy]
------------------------------------------------------
def firstname, lastname
(firstname, lastname) = "Guillaume Laforge".tokenize()
assert firstname == "Guillaume"
assert lastname == "Laforge"
------------------------------------------------------
If the list on the right-hand side contains more elements than the
number of variables on the left-hand side, only the first elements will
be assigned in order into the variables. Also, when there are less
elements than variables, the extra variables will be assigned null.
So for the case with more variables than list elements, here`c` will
be `null`:
[source,groovy]
------------------------
def elements = [1, 2]
def (a, b, c) = elements
assert a == 1
assert b == 2
assert c == null
------------------------
Whereas in the case where there are more list elements than variables,
well get the following expectations:
[source,groovy]
---------------------------
def elements = [1, 2, 3, 4]
def (a, b, c) = elements
assert a == 1
assert b == 2
assert c == 3
---------------------------
For the curious minds, supporting multiple assignments also means we can
do the standard school swap case in one line:
[source,groovy]
-----------------------------
// given those two variables
def a = 1, b = 2
// swap variables with a list
(a, b) = [b, a]
assert a == 2
assert b == 1
-----------------------------
[[Groovy16releasenotes-Annotationdefinition]]
== Annotation definition
Actually, when I said that multiple assignments were the sole syntax
addition, its not entirely true. Groovy supported the syntax for
annotation definition even in Groovy 1.5, but we had not implemented the
feature completely. Fortunately, this is now fixed, and it wraps up all
the Java 5 features supported by Groovy, such as *static
imports*, *generics*, *annotations*, and *enums*, making Groovy
the *sole alternative dynamic language for the JVM supporting all those
Java 5 features*, which is critical for a seamless Java integration
story, and for the usage in Enterprise frameworks relying on
annotations, generics and more, like JPA, EJB3, Spring, TestNG, etc.
[[Groovy16releasenotes-Optionalreturnforifelseandtrycatchfinallyblocks]]
== Optional return for if/else and try/catch/finally blocks
It is now possible for `if/else` and `try/catch/finally` blocks to
return a value when they are the last expression in a method or a
closure. No need to explicitly use the `return` keyword inside these
constructs, as long as they are the latest expression in the block of
code.
As an example, the following method will return `1`, although
the `return` keyword was omitted.
[source,groovy]
----------------------
def method() {
if (true) 1 else 0
}
assert method() == 1
----------------------
For `try/catch/finally` blocks, the last expression evaluated is the one
being returned. If an exception is thrown in the `try` block, the last
expression in the `catch` block is returned instead. Note
that `finally` blocks dont return any value.
[source,groovy]
--------------------------------------------
def method(bool) {
try {
if (bool) throw new Exception("foo")
1
} catch(e) {
2
} finally {
3
}
}
assert method(false) == 1
assert method(true) == 2
--------------------------------------------
[[Groovy16releasenotes-ASTTransformations]]
== AST Transformations
Although at times, it may sound like a good idea to extend the syntax of
Groovy to implement new features (like this is the case for instance for
multiple assignments), most of the time, we cant just add a new keyword
to the grammar, or create some new syntax construct to represent a new
concept. However, with the idea of AST (Abstract Syntax Tree)
Transformations, we are able to tackle new and innovative ideas without
necessary grammar changes.
When the Groovy compiler compiles Groovy scripts and classes, at some
point in the process, the source code will end up being represented in
memory in the form of a Concrete Syntax Tree, then transformed into an
Abstract Syntax Tree. The purpose of AST Transformations is to let
developers hook into the compilation process to be able to modify the
AST before it is turned into bytecode that will be run by the JVM.
*AST Transformations provides Groovy with improved compile-time
metaprogramming capabilitiesallowing powerful flexibility at the
language level, without a runtime performance penalty.
There are two kinds of transformations: global and local
transformations.
* Global transformations are applied to by the compiler on the code
being compiled, wherever the transformation apply. A JAR added to the
classpath of the compiler should contain a service locator file
at `META-INF/services/org.codehaus.groovy.transform.ASTTransformation` with
a line with the name of the transformation class. The transformation
class must have a no-args constructor and implement
the `org.codehaus.groovy.transform.ASTTransformation`interface. It will
be run against every source in the compilation, so be sure to not create
transformations which scan all the AST in an expansive and
time-consuming manner, to keep the compiler fast.
* Local transformations are transformations applied locally by
annotating code elements you want to transform. For this, we reuse the
annotation notation, and those annotations should
implement `org.codehaus.groovy.transform.ASTTransformation`. The
compiler will discover them and apply the transformation on these code
elements.
Groovy 1.6 provides several local transformation annotations, in the
Groovy Swing Builder for data binding (`@Bindable` and `@Vetoable`), in
the Grape module system for adding script library dependencies
(`@Grab`), or as general language features without requiring any syntax
change to support them
(`@Singleton``@Immutable``@Delegate``@Lazy``@Newify``@Category``@Mixin` and `@PackageScope`).
Lets have a look at some of these transformations
(`@Bindable` and `@Vetoable` will be covered in the section related to
the Swing enhancements, and `@Grab` in the section about Grape).
[[Groovy16releasenotes-Singleton]]
=== @Singleton
Whether the singleton is pattern or an anti-pattern, there are still
some cases where we need to create singletons. Were used to create a
private constructor,`getInstance()` method for a static field or even
an initialized `public static final` field. So instead of writing code
like this in Java:
[source,groovy]
---------------------------------------------
public class T {
public static final T instance = new T();
private T() {}
}
---------------------------------------------
You just need to annotate your type with the `@Singleton` annotation:
[source,groovy]
---------------------
@Singleton class T {}
---------------------
The singleton instance can then simply be accessed
with `T.instance` (direct public field access).
You can also have the lazy loading approach with an additional
annotation parameter:
[source,groovy]
----------------------------------
@Singleton(lazy = true) class T {}
----------------------------------
Would become more or less equivalent to this Groovy class:
[source,groovy]
---------------------------------------
class T {
private static volatile T instance
private T() {}
static T getInstance () {
if (instance) {
instance
} else {
synchronized(T) {
if (instance) {
instance
} else {
instance = new T ()
}
}
}
}
}
---------------------------------------
Lazy or not, once again, to access the instance, simply
do `T.instance` (property access, shorcut for `T.getInstance()`).
[[Groovy16releasenotes-Immutable]]
=== @Immutable
Immutable objects are ones which dont change after initial creation.
Such objects are frequently desirable because they are simple and can be
safely shared even in multi-threading contexts. This makes them great
for functional and concurrent scenarios. The rules for creating such
objects are well-known:
* No mutators (methods that modify internal state)
* Class must be final
* Fields must be private and final
* Defensive copying of mutable components
* `equals()``hashCode()` and `toString()` must be implemented in terms
of the fields if you want to compare your objects or use them as keys in
e.g. maps
Instead of writing a very long Java or Groovy class mimicking this
immutability behavior, Groovy lets you just write an immutable class as
follow:
 
[source,groovy]
------------------------------------------------------------------
@Immutable final class Coordinates {
Double latitude, longitude
}
def c1 = new Coordinates(latitude: 48.824068, longitude: 2.531733)
def c2 = new Coordinates(48.824068, 2.531733)
assert c1 == c2
------------------------------------------------------------------
All the boiler-plate code is generated at compile-time for you! The
example shows that to instantiate such immutable coordinates, you can
use one of the two constructors created by the transformation, one
taking a map whose keys are the properties to set to the values
associated with those keys, and the other taking the values of the
properties as parameters. The `assert` also shows that `equals()` was
implemented and allows us to properly compare such immutable objects.
You can have a look at
the link:http://docs.groovy-lang.org/latest/html/gapi/groovy/transform/Immutable.html[details of the implementation] of this transformation. For the record, the Groovy
example above using the`@Immutable` transformation is over 50 lines of
equivalent Java code.
[[Groovy16releasenotes-Lazy]]
=== @Lazy
Another transformation is `@Lazy`. Sometimes, you want to handle the
initialization of a field of your clas lazily, so that its value is
computed only on first use, often because it may be time-consuming or
memory-expensive to create. The usual approach is to customize the
getter of said field, so that it takes care of the initialization when
the getter is called the first time. But in Groovy 1.6, you can now use
the `@Lazy` annotation for that purpose:
[source,groovy]
---------------------------------------
class Person {
@Lazy pets = ['Cat', 'Dog', 'Bird']
}
def p = new Person()
assert !(p.dump().contains('Cat'))
assert p.pets.size() == 3
assert p.dump().contains('Cat')
---------------------------------------
In the case of complex computation for initializing the field, you may
need to call some method for doing the work, instead of a value like our
pets list. This is then possible to have the lazy evaluation being done
by a closure call, as the following example shows:
[source,groovy]
----------------------------------------------------------
class Person {
@Lazy List pets = { /* complex computation here */ }()
}
----------------------------------------------------------
There is also an option for leveraging Soft references for garbage
collection friendliness for expensive data structures that may be
contained by such lazy fields:
[source,groovy]
---------------------------------------------------------
class Person {
@Lazy(soft = true) List pets = ['Cat', 'Dog', 'Bird']
}
def p = new Person()
assert p.pets.contains('Cat')
---------------------------------------------------------
The internal field created by the compiler for `pets` will actually be a
Soft reference, but accessing `p.pets` directly will return the value
(ie. the list of pets) held by that reference, making the use of the
soft reference transparent to the user of that class.
[[Groovy16releasenotes-Delegate]]
=== @Delegate
Java doesnt provide any built-in delegation mechanism, and so far
Groovy didnt either. But with the `@Delegate` transformation, a class
field or property can be annotated and become an object to which method
calls are delegated. In the following example, an `Event` class has a
date delegate, and the compiler will delegate all of `Date`s methods
invoked on the `Event` class to the `Date` delegate. As shown in the
latest `assert`, the `Event` class has got a `before(Date)` method, and
all of `Date`s methods.
[source,groovy]
--------------------------------------------------------------
import java.text.SimpleDateFormat
class Event {
@Delegate Date when
String title, url
}
def df = new SimpleDateFormat("yyyy/MM/dd")
def gr8conf = new Event(title: "GR8 Conference",
url: "http://www.gr8conf.org",
when: df.parse("2009/05/18"))
def javaOne = new Event(title: "JavaOne",
url: "http://java.sun.com/javaone/",
when: df.parse("2009/06/02"))
assert gr8conf.before(javaOne.when)
--------------------------------------------------------------
The Groovy compiler adds all of `Date`s methods to the `Event` class,
and those methods simply delegate the call to the `Date` field. If the
delegate is not a final class, it is even possible to make
the `Event` class a subclass of `Date` simply by extending `Date`, as
shown below. No need to implement the delegation ourselves by adding
each and every `Date` methods to our `Event` class, since the compiler
is friendly-enough with us to do the job itself.
[source,groovy]
--------------------------
class Event extends Date {
@Delegate Date when
String title, url
}
--------------------------
In the case you are delegating to an interface, however, you dont even
need to explictely say you implement the interface of the delegate.
The `@Delegate` transformation will take care of this and implement that
interface. So the instances of your class will automatically
be `instanceof` the delegates interface.
[source,groovy]
-----------------------------------------------------
import java.util.concurrent.locks.*
class LockableList {
@Delegate private List list = []
@Delegate private Lock lock = new ReentrantLock()
}
def list = new LockableList()
list.lock()
try {
list << 'Groovy'
list << 'Grails'
list << 'Griffon'
} finally {
list.unlock()
}
assert list.size() == 3
assert list instanceof Lock
assert list instanceof List
-----------------------------------------------------
In this example, our `LockableList` is now a composite of a list and a
lock and is `instanceof` of `List` and `Lock`. However, if you didnt
intend your class to be implementing these interfaces, you would still
be able to do so by specifying a parameter on the annotation:
[source,groovy]
----------------------------------------------------
@Delegate(interfaces = false) private List list = []
----------------------------------------------------
[[Groovy16releasenotes-Newify]]
=== @Newify
The `@Newify` transformation proposes two new ways of instantiating
classes. The first one is providing Ruby like approach to creating
instances with`new()` class method:
[source,groovy]
--------------------------------
@Newify rubyLikeNew() {
assert Integer.new(42) == 42
}
rubyLikeNew()
--------------------------------
But it is also possible to follow the Python approach with omitting
the `new` keyword. Imagine the following tree creation:
[source,groovy]
-----------------------------------------------------------------
class Tree {
def elements
Tree(Object... elements) { this.elements = elements as List }
}
class Leaf {
def value
Leaf(value) { this.value = value }
}
def buildTree() {
new Tree(new Tree(new Leaf(1), new Leaf(2)), new Leaf(3))
}
buildTree()
-----------------------------------------------------------------
The creation of the tree is not very readable because of all
those `new` keywords spread across the line. The Ruby approach wouldnt
be more readable, since a `new()` method call for creating each element
is needed. But by using `@Newify`, we can improve our tree building
slightly to make it easier on the eye:
[source,groovy]
-----------------------------------------
@Newify([Tree, Leaf]) buildTree() {
Tree(Tree(Leaf(1), Leaf(2)), Leaf(3))
}
-----------------------------------------
Youll also notice that we just allowed `Tree` and `Leaf` to
be _newified_. By default, under the scope which is annotated, all
instantiations are_newified_, but you can limit the reach by specifying
the classes youre interested in. Also, note that for our example,
perhaps a Groovy builder may have been more appropriate, since its
purpose is to indeed create any kind of hierarchical / tree strucutre.
If we take another look at our coordinates example from a few sections
earlier, using both `@Immutable` and `@Newify` can be interesting for
creating a path with a concise but type-safe manner:
[source,groovy]
-----------------------------------------
@Immutable final class Coordinates {
Double latitude, longitude
}
@Immutable final class Path {
Coordinates[] coordinates
}
@Newify([Coordinates, Path])
def build() {
Path(
Coordinates(48.824068, 2.531733),
Coordinates(48.857840, 2.347212),
Coordinates(48.858429, 2.342622)
)
}
assert build().coordinates.size() == 3
-----------------------------------------
A closing remark here: since a `Path(Coordinates[] coordinates)` was
generated, we can use that constructor in a _varargs way_ in Groovy,
just as if it had been defined as `Path(Coordinates... coordinates)`.
[[Groovy16releasenotes-CategoryandMixin]]
=== @Category and @Mixin
If youve been using Groovy for a while, youre certainly familiar with
the concept of Categories. Its a mechanism to extend existing types
(even final classes from the JDK or third-party libraries), to add new
methods to them. This is also a technique which can be used when writing
Domain-Specific Languages. Lets consider the example below:
[source,groovy]
--------------------------------------------
final class Distance {
def number
String toString() { "${number}m" }
}
class NumberCategory {
static Distance getMeters(Number self) {
new Distance(number: self)
}
}
use(NumberCategory) {
def dist = 300.meters
assert dist instanceof Distance
assert dist.toString() == "300m"
}
--------------------------------------------
We have a simplistic and fictive `Distance` class which may have been
provided by a third-party, who had the bad idea of making the
class`final` so that nobody could ever extend it in any way. But thanks
to a Groovy Category, we are able to decorate the `Distance` type with
additional methods. Here, were going to add a `getMeters()` method to
numbers, by actually decorating the `Number` type. By adding a getter to
a number, youre able to reference it using the nice property syntax of
Groovy. So instead of writing `300.getMeters()`, youre able to
write `300.meters`.
The downside of this category system and notation is that to add
instance methods to other types, you have to create `static` methods,
and furthermore, theres a first argument which represents the instance
of the type were working on. The other arguments are the normal
arguments the method will take as parameters. So it may be a bit less
intuitive than a normal method definition we would have added
to `Distance`, should we have had access to its source code for
enhancing it. Here comes the `@Category` annotation, which transforms a
class with instance methods into a Groovy category:
[source,groovy]
----------------------------------
@Category(Number)
class NumberCategory {
Distance getMeters() {
new Distance(number: this)
}
}
----------------------------------
No need for declaring the methods `static`, and the `this` you use here
is actually the number on which the category will apply, its not the
real `this` of the category instance should we create one. Then to use
the category, you can continue to use the `use(Category) {}`construct.
What youll notice however is that these kind of categories only apply
to one single type at a time, unlike classical categories which can be
applied to any number of types.
Now, pair `@Category` extensions to the `@Mixin` transformation, and you
can mix in various behavior in a class, with an approach similar to
multiple inheritance:
[source,groovy]
-------------------------------------------------
@Category(Vehicle) class FlyingAbility {
def fly() { "I'm the ${name} and I fly!" }
}
@Category(Vehicle) class DivingAbility {
def dive() { "I'm the ${name} and I dive!" }
}
interface Vehicle {
String getName()
}
@Mixin(DivingAbility)
class Submarine implements Vehicle {
String getName() { "Yellow Submarine" }
}
@Mixin(FlyingAbility)
class Plane implements Vehicle {
String getName() { "Concorde" }
}
@Mixin([DivingAbility, FlyingAbility])
class JamesBondVehicle implements Vehicle {
String getName() { "James Bond's vehicle" }
}
assert new Plane().fly() ==
"I'm the Concorde and I fly!"
assert new Submarine().dive() ==
"I'm the Yellow Submarine and I dive!"
assert new JamesBondVehicle().fly() ==
"I'm the James Bond's vehicle and I fly!"
assert new JamesBondVehicle().dive() ==
"I'm the James Bond's vehicle and I dive!"
-------------------------------------------------
You dont inherit from various interfaces and inject the same behavior
in each subclass, instead you mixin the categories into your class.
Here, our marvelous James Bond vehicle gets the flying and diving
capabilities through mixins.
An important point to make here is that unlike `@Delegate` which
can _inject_ interfaces into the class in which the delegate is
declared,`@Mixin` just does runtime mixing as we shall see in the
metaprogramming enhancements further down in this article.
[[Groovy16releasenotes-PackageScope]]
=== @PackageScope
Groovys convention for properties is that any _field_ without any
visibility modifier is exposed as a property, with a getter and a setter
transparently generated for you. For instance, this `Person` class
exposes a getter `getName()` and a setter `setName()` for a
private `name` field:
[source,groovy]
---------------
class Person {
String name
}
---------------
Which is equivalent to this Java class:
[source,groovy]
---------------------------------------------------
public class Person {
private String name;
public String getName() { return name; }
public void setName(name) { this.name = name; }
}
---------------------------------------------------
That said, this approach has one drawback in that you dont have the
possibility to define a field with package-scope visibility. To be able
to expose a field with package-scope visibility, you can now annotate
your field with the `@PackageScope` annotation.
[[Groovy16releasenotes-GrapetheGroovyAdaptableAdvancedPackagingEngine]]
== Grape, the Groovy Adaptable / Advanced Packaging Engine
To continue our overview of the AST transformations, well now learn
more about Grape, a mechanism to add and leverage dependencies in your
Groovy scripts. Groovy scripts can require certain libraries: by
explicitly saying so in your script with the *@Grabtransformation or
with the *Grape.grab()* method call, the runtime will find the needed
JARs for you. With Grape, you can easily distribute scripts without
their dependencies, and have them downloaded on first use of your script
and cached. Under the hood, Grape uses Ivy and Maven repositories
containing the libraries you may need in your scripts.
Imagine you want to get the links of all the PDF documents referenced by
the Java 5 documentation. You want to parse the HTML page as if it were
an XML-compliant document (which it is not) with the Groovy `XmlParser`,
so you can use the TagSoup SAX-compliant parser which transforms HTML
into well-formed valid XML. You dont even have to mess up with your
classpath when running your script, just_grab_ the TagSoup library
through Grape:
[source,groovy]
------------------------------------------------------------------------
import org.ccil.cowan.tagsoup.Parser
// find the PDF links in the Java 1.5.0 documentation
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')
def getHtml() {
def tagsoupParser = new Parser()
def parser = new XmlParser(tagsoupParser)
parser.parse("http://java.sun.com/j2se/1.5.0/download-pdf.html")
}
html.body.'**'.a.@href.grep(~/.*\.pdf/).each{ println it }
------------------------------------------------------------------------
For the pleasure of giving another example: lets use
the link:http://eclipse.org/jetty/[Jetty servlet container] to
expose link:{DOCS_BASEURL}/html/documentation/template-engines.html[Groovy templatesin
a few lines of code:
[source,groovy]
--------------------------------------------------------------------------------
import org.mortbay.jetty.Server
import org.mortbay.jetty.servlet.*
import groovy.servlet.*
@Grab(group = 'org.mortbay.jetty', module = 'jetty-embedded', version = '6.1.0')
def runServer(duration) {
def server = new Server(8080)
def context = new Context(server, "/", Context.SESSIONS);
context.resourceBase = "."
context.addServlet(TemplateServlet, "*.gsp")
server.start()
sleep duration
server.stop()
}
runServer(10000)
--------------------------------------------------------------------------------
Grape will download Jetty and its dependencies on first launch of this
script, and cache them. Were creating a new Jetty `Server` on port
8080, then expose Groovy`TemplateServlet` at the root of the context
Groovy comes with its own powerful template engine mechanism. We start
the server and let it run for a certain duration. Each time someone will
hit +http://localhost:8080/somepage.gsp+, it will display
the `somepage.gsp` template to the user those template pages should be
situated in the same directory as this server script.
Grape can also be used as a method call instead of as an annotation. You
can also install, list, resolve dependencies from the command-line using
the `grape` command. For link:../grape.html[more information on Grape], please refer to the documentation.
[[Groovy16releasenotes-Swingbuilderimprovements]]
== Swing builder improvements
To wrap up our overview of AST transformations, lets finish by speaking
about two transformations very useful to Swing
developers:`@Bindable` and `@Vetoable`. When creating Swing UIs, youre
often interested in monitoring the changes of value of certain UI
elements. For this purpose, the usual approach is to use
JavaBeans `PropertyChangeListener`s to be notified when the value of a
class field changes. You then end up writing this very common
boiler-plate code in your Java beans:
[source,groovy]
------------------------------------------------------------------------
import com.googlecode.openbeans.PropertyChangeSupport;
import com.googlecode.openbeans.PropertyChangeListener;
public class MyBean {
private String prop;
PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener l) {
pcs.add(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
pcs.remove(l);
}
public String getProp() {
return prop;
}
public void setProp(String prop) {
pcs.firePropertyChanged("prop", this.prop, this.prop = prop);
}
}
------------------------------------------------------------------------
Fortunately, with Groovy and the `@Bindable` annotation, this code can
be greatly simplified:
[source,groovy]
-------------------------
class MyBean {
@Bindable String prop
}
-------------------------
Now pair that with Groovys Swing builder new `bind()` method, define a
text field and bind its value to a property of your data model:
[source,groovy]
--------------------------------------------------------------------
textField text: bind(source: myBeanInstance, sourceProperty: 'prop')
--------------------------------------------------------------------
Or even:
[source,groovy]
--------------------------------------------
textField text: bind { myBeanInstance.prop }
--------------------------------------------
The binding also works with simple expressions in the closure, for
instance something like this is possible too:
[source,groovy]
--------------------------------------------
bean location: bind { pos.x + ', ' + pos.y }
--------------------------------------------
You may also be interested in having a look
at link:{DOCS_BASEURL}/html/api/groovy/util/ObservableMap.html[ObservableMapand link:{DOCS_BASEURL}/html/api/groovy/util/ObservableList.html[ObservableList],
for a similar mechanism on maps and lists.
Along with `@Bindable`, theres also a `@Vetoable` transformation for
when you need to be able to veto some property change. Lets consider
`Trompetist` class, where the performers name is not allowed to
contain the letter `z':
[source,groovy]
---------------------------------------------------------------------------------------
import com.googlecode.openbeans.*
import groovy.beans.Vetoable
class Trumpetist {
@Vetoable String name
}
def me = new Trumpetist()
me.vetoableChange = { PropertyChangeEvent pce ->
if (pce.newValue.contains('z'))
throw new PropertyVetoException("The letter 'z' is not allowed in a name", pce)
}
me.name = "Louis Armstrong"
try {
me.name = "Dizzy Gillespie"
assert false: "You should not be able to set a name with letter 'z' in it."
} catch (PropertyVetoException pve) {
assert true
}
---------------------------------------------------------------------------------------
Looking at a more thorough Swing builder example with binding:
[source,groovy]
----------------------------------------------------------------------------
import groovy.swing.SwingBuilder
import groovy.beans.Bindable
import static javax.swing.JFrame.EXIT_ON_CLOSE
class TextModel {
@Bindable String text
}
def textModel = new TextModel()
SwingBuilder.build {
frame( title: 'Binding Example (Groovy)', size: [240,100], show: true,
locationRelativeTo: null, defaultCloseOperation: EXIT_ON_CLOSE ) {
gridLayout cols: 1, rows: 2
textField id: 'textField'
bean textModel, text: bind{ textField.text }
label text: bind{ textModel.text }
}
}
----------------------------------------------------------------------------
Running this script shows up the frame below with a text field and a
lable below, and the label’s text is bound on the text field’s content.
image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/bindable-example.png[image]
SwingBuilder has evolved so nicely in the past year that the Groovy
Swing team decided to launch a new project based on it, and on the
Grails foundations: project link:http://griffon-framework.org/[Griffon] was
born. Griffon proposes to bring the _Convention over
Configuration_ paradigm of Grails, as well as all its project structure,
plugin system, gant scripting capabilities, etc.
If you are developing Swing rich clients, make sure to have a look
at link:http://griffon-framework.org/[Griffon].
[[Groovy16releasenotes-Swingconsoleimprovements]]
== Swing console improvements
Swinging along the topic of UIs, the Swing console has also evolved:
* The console can be run as an Applet (`groovy.ui.ConsoleApplet`).
* Beyond syntax highlighting, the editor also supports code indentation.
* Drag’n droping a Groovy script over the text area will open the file.
* You can modify the classpath with which the script in the console is
being run, by adding a new JAR or a directory to the classpath as shown
in the screenshot below.
+
+
image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-add-jar.png[image]
+
* A couple options have been added to the view menu item: for showing
the script being run in the output area, and for visualizing the
execution results.
+
+
image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-options.png[image]
+
* When an exception is thrown in your script, the lines of the
stacktrace relative to your script are clickable, for easy navigation to
the point where the error occurred.
+
+
image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-click-stack.png[image]
+
* Also, when your script contains compilation errors, the error messages
are clickable too.
+
+
image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-click-comp-error.png[image]
+
Back on the visualization of the results in the script output area, a
fun system was added to let you customize how certain results are
rendered. When you execute a script returning a map of Jazz musicians,
you may see something like this in your console:
image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-without-visu.png[image]
What you see here is the usual textual representation of a `Map`. But,
what if we enabled custom visualization of certain results? The Swing
console allows you to do just that. First of all, you have to ensure
that the visualization option is
ticked: `View -> Visualize Script Results` — for the record, all
settings of the Groovy Console are stored and remembered thanks to the
Preference API. There are a few result visualizations built-in: if the
script returns a `java.awt.Image`, a `javax.swing.Icon`, or
a `java.awt.Component` with no parent, the object is displayed instead
of its `toString()` representation. Otherwise, everything else is still
just represented as text. Now, create the following Groovy script
in `~/.groovy/OutputTransforms.groovy`:
[source,groovy]
---------------------------------------------------------
import javax.swing.*
transforms << { result ->
if (result instanceof Map) {
def table = new JTable(
result.collect{ k, v -<
[k, v?.inspect()] as Object[]
} as Object[][],
['Key', 'Value'] as Object[])
table.preferredViewportSize = table.preferredSize
return new JScrollPane(table)
}
}
---------------------------------------------------------
The Groovy Swing console will execute that script on startup, injecting
a `transforms` list in the binding of the script, so that you can add
your own script results representations. In our case, we transform
the `Map` into a nice-looking Swing `JTable`. And we’re now able to
visualize maps in a friendly and attractive fashion, as the screenshot
below
shows:image:http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-with-visu.png[image]
The Swing console is obviously not to be confused with a real full-blown
IDE, but for daily scripting tasks, the console is a handy tool in your
toolbox.
[[Groovy16releasenotes-Metaprogrammingenhancements]]
== Metaprogramming enhancements
What makes Groovy a dynamic language is its Meta-Object Protocol and its
concept of metaclasses which represent the runtime behavior of your
classes and instances. In Groovy 1.6, we continue improving this dynamic
runtime system, bringing several new capabilities into the mix.
[[Groovy16releasenotes-PerinstancemetaclassevenforPOJOs]]
=== Per instance metaclass even for POJOs
So far, Groovy POGOs (Plain Old Groovy Objects) could have a
per-instance metaclass, but POJOs could only have one metaclass for all
instances (ie. a per-class metaclass). This is now not the case anymore,
as POJOs can have a per-instance metaclass too. Also, setting the
metaclass property to null will restore the default metaclass.
[[Groovy16releasenotes-ExpandoMetaClassDSL]]
=== ExpandoMetaClass DSL
Initially developed under the link:http://grails.org/[Grails] umbrella and
integrated back into Groovy 1.5, ExpandoMetaClass is a very handy way
for changing the runtime behavior of your objects and classes, instead
of writing full-blow `MetaClass` classes. Each time, we want to add /
change several properties or methods of an existing type, there is too
much of a repetition of `Type.metaClass.xxx`. Take for example this
extract of
a link:http://groovy.dzone.com/news/domain-specific-language-unit-[Unit
manipulation DSL] dealing with operator overloading:
[source,groovy]
---------------------------------------------------------------------------------
Number.metaClass.multiply = { Amount amount -> amount.times(delegate) }
Number.metaClass.div = { Amount amount -> amount.inverse().times(delegate) }
Amount.metaClass.div = { Number factor -> delegate.divide(factor) }
Amount.metaClass.div = { Amount factor -> delegate.divide(factor) }
Amount.metaClass.multiply = { Number factor -> delegate.times(factor) }
Amount.metaClass.power = { Number factor -> delegate.pow(factor) }
Amount.metaClass.negative = { -> delegate.opposite() }
---------------------------------------------------------------------------------
The repetition, here, looks obvious. But with the ExpandoMetaClass DSL,
we can streamline the code by regrouping the operators per type:
[source,groovy]
------------------------------------------------------------------
Number.metaClass {
multiply { Amount amount -> amount.times(delegate) }
div { Amount amount -> amount.inverse().times(delegate) }
}
Amount.metaClass {
div << { Number factor -> delegate.divide(factor) }
div << { Amount factor -> delegate.divide(factor) }
multiply { Number factor -> delegate.times(factor) }
power { Number factor -> delegate.pow(factor) }
negative { -> delegate.opposite() }
}
------------------------------------------------------------------
A `metaClass()` method takes a closure as single argument, containing
the various definitions of the methods and properties, instead of
repeating the `Type.metaClass` on each line. When there is just one
method of a given name, use the pattern `methodName { /* closure */ }`,
but when there are several, you should use the append operator and
follow the patten `methodName << { /* closure */ }`. Static methods can
also be added through this mechanism, so instead of the classical
approach:
[source,groovy]
---------------------------------------------------------
// add a fqn() method to Class to get the fully
// qualified name of the class (ie. simply Class#getName)
Class.metaClass.static.fqn = { delegate.name }
assert String.fqn() == "java.lang.String"
---------------------------------------------------------
You can now do:
[source,groovy]
-----------------------------
Class.metaClass {
'static' {
fqn { delegate.name }
}
}
-----------------------------
Note here that you have to quote the `static` keyword, to avoid this
construct to look like a static initializer. For one off method
addition, the classical approach is obviously more concise, but when you
have several methods to add, the EMC DSL makes sense.
The usual approach for adding properties to existing classes through
ExpandoMetaClass is to add a getter and a setter as methods. For
instance, say you want to add a method that counts the number of words
in a text file, you could try this:
[source,groovy]
------------------------------------
File.metaClass.getWordCount = {
delegate.text.split(/\w/).size()
}
new File('myFile.txt').wordCount
------------------------------------
When there is some logic inside the getter, this is certainly the best
approach, but when you just want to have new properties holding simple
values, through the ExpandoMetaClass DSL, it is possible to define them.
In the following example, a `lastAccessed` property is added to
a `Car` class — each instance will have its property. Whenever a method
is called on that car, this property is updated with a newer timestamp.
[source,groovy]
------------------------------------------------------------------------
class Car {
void turnOn() {}
void drive() {}
void turnOff() {}
}
Car.metaClass {
lastAccessed = null
invokeMethod = { String name, args ->
def metaMethod = delegate.metaClass.getMetaMethod(name, args)
if (metaMethod) {
delegate.lastAccessed = new Date()
metaMethod.doMethodInvoke(delegate, args)
} else {
throw new MissingMethodException(name, delegate.class, args)
}
}
}
def car = new Car()
println "Last accessed: ${car.lastAccessed ?: 'Never'}"
car.turnOn()
println "Last accessed: ${car.lastAccessed ?: 'Never'}"
car.drive()
sleep 1000
println "Last accessed: ${car.lastAccessed ?: 'Never'}"
sleep 1000
car.turnOff()
println "Last accessed: ${car.lastAccessed ?: 'Never'}"
------------------------------------------------------------------------
In our example, in the DSL, we access that property through
the `delegate` of the closure,
with `delegate.lastAccessed = new Date()`. And we intercept any method
call thanks to `invokeMethod()`, delegating to the original method for
the call, and throwing an exception in case the method doesn’t exist.
Later on, you can see by executing this script that `lastAccessed` is
updated as soon as we call a method on our instance.
[[Groovy16releasenotes-Runtimemixins]]
=== Runtime mixins
Last metaprogramming feature we’ll cover today: runtime
mixins. `@Mixin` allowed you to mixin new behavior to classes you owned
and were designing. But you could not mixin anything to types you didn’t
own. Runtime mixins propose to fill that gap by letting you add a mixin
on any type at runtime. If we think again about our example of vehicles
with some mixed-in capabilities, if we didn’t _own_ James Bond’s vehicle
and give it some diving ability, we could use this mechanism:
[source,groovy]
---------------------------------------------------
// provided by a third-party
interface Vehicle {
String getName()
}
// provided by a third-party
class JamesBondVehicle implements Vehicle {
String getName() { "James Bond's vehicle" }
}
JamesBondVehicle.mixin DivingAbility, FlyingAbility
assert new JamesBondVehicle().fly() ==
"I'm the James Bond's vehicle and I fly!"
assert new JamesBondVehicle().dive() ==
"I'm the James Bond's vehicle and I dive!"
---------------------------------------------------
One or more mixins can be passed as argument to the
static `mixin()` method added by Groovy on `Class`.
[[Groovy16releasenotes-JSR-223GroovyScriptingEngine]]
== JSR-223 Groovy Scripting Engine
Before Groovy 1.6, if you wanted to integrate Groovy in your Java
projects through JSR-223 / `javax.script.*`, you had to download a
Groovy script engine implementation from java.net, and put the JAR in
your classpath. This additional step wasn’t very developer friendly,
requiring some additional work — the JAR wasn’t even provided in the
Groovy distribution. Thankfully, 1.6 comes with an implementation of
the `javax.script.*` APIs.
Below, you’ll find an example evaluating Groovy expressions (the code is
in Groovy, but it’s straightforward to convert it back to Java):
[source,groovy]
----------------------------------------------
import javax.script.*
def manager = new ScriptEngineManager()
def engine = manager.getEngineByName("groovy")
assert engine.evaluate("2 + 3") == 5
----------------------------------------------
Please note that the `javax.script.*` APIs are available only on Java 6.
[[Groovy16releasenotes-JMXBuilder]]
== JMX Builder
Originiating as an link:http://code.google.com/p/groovy-jmx-builder/[external
Open-Source project] hosted on Google Code, JMX Builder has been
integrated in Groovy 1.6, to simplify the life of developers needing to
interact or expose JMX services. JMX Builder features:
* Domain Specific Language (DSL) for JMX API using Builder pattern
* Simplified JMX API’s programmability
* Declaratively expose Java/Groovy objects as JMX managed MBeans
* Support class-embedded or explicit descriptors
* Inherent support for JMX’s event model
* Seamlessly create JMX event broadcasters
* Attach event listeners as inline closures
* Use Groovy’s dynamic nature to easily react to JMX events
notifications
* Provides a flexible registration policy for MBean
* No special interfaces or class path restrictions
* Shields developer from complexity of JMX API
* Exposes attribute, constructors, operations, parameters, and
notifications
* Simplifies the creation of connector servers and connector clients
* Support for exporting JMX timers
You can find link:../jmx.html[more information on JMX Builder] and its very extensive coverage of the JMX
system. Lots of examples will show you how to create a JMX connector
server or client, how to easily export POGOs as JMX managed beans, how
to listen to JMX events, and much more.
[[Groovy16releasenotes-ImprovedOSGisupport]]
== Improved OSGi support
The Groovy jar files are released with correct OSGi metadata, so they
can be loaded as a bundle into any OSGi compliant container, such as
Eclipse Equinox or Apache Felix.
[[Groovy16releasenotes-Summary]]
== Summary
Groovy continues its march towards the goal of *simplifying the life of
developers*, providing various new features and improvements in this new
release: AST transformations reducing dramatically the number of lines
of code to express certain concerns and patterns and opening the
language to developers for further extension, several *metaprogramming
enhancements to streamline your code* and let you write *more expressive
business rules*, and *support for common enterprise APIs* such as Java
6’s scripting APIs, JMX management system, or OSGi’s programming model.
All of this is done obviously *without compromising on the seamless
integration with Java*, and furthermore, with a *level of performance
way higher than previous releases*.