== 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 transformations* and 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-223* scripting 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 overall 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,
it's a whole ecosystem*.

The improvements in Groovy's 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, Groovy's flexibility and expressiveness 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, it's 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 faster* than in previous releases. This
improvement has also been back-ported 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:https://salsa.debian.org/benchmarksgame-team/archive-alioth-benchmarksgame/tree/master/contributed-source-code/shootout[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 overall 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 meaningful example may be methods returning longitude 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,
we'll 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, it's 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 don't 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 can't 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 capabilities* allowing 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`).
Let's 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. We're used to create a
private constructor, a `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, shortcut for `T.getInstance()`).

[[Groovy16releasenotes-Immutable]]
=== @Immutable

Immutable objects are ones which don't 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 class 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 doesn't provide any built-in delegation mechanism, and so far
Groovy didn't 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 don't even
need to explicitly 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 delegate's 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 didn't
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 a `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 wouldn't
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))
}
-----------------------------------------

You'll 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 you're 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 structure.

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 you've been using Groovy for a while, you're certainly familiar with
the concept of Categories. It's 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. Let's 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, we're going to add a `getMeters()` method to
numbers, by actually decorating the `Number` type. By adding a getter to
a number, you're able to reference it using the nice property syntax of
Groovy. So instead of writing `300.getMeters()`, you're 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, there's a first argument which represents the instance
of the type we're 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, it's 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 you'll 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 don't 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

Groovy's 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 don't 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, we'll 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 *@Grab* transformation 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 don't 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: let's use
the link:http://eclipse.org/jetty/[Jetty servlet container] to
expose link:{DOCS_BASEURL}/html/documentation/template-engines.html[Groovy templates] in
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. We're creating a new Jetty `Server` on port
8080, then expose Groovy's `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, let's finish by speaking
about two transformations very useful to Swing
developers:`@Bindable` and `@Vetoable`. When creating Swing UIs, you're
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 Groovy's 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[ObservableMap] and link:{DOCS_BASEURL}/html/api/groovy/util/ObservableList.html[ObservableList],
for a similar mechanism on maps and lists.

Along with `@Bindable`, there's also a `@Vetoable` transformation for
when you need to be able to veto some property change. Let's consider
a `Trumpetist` class, where the performer's 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
label below, and the label's text is bound on the text field's content.

image:https://web.archive.org/web/20160102200635/http://www.infoq.com/resource/articles/groovy-1-6/en/resources/sc-without-visu.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'dropping 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:https://web.archive.org/web/20160102200636/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:https://web.archive.org/web/20160102200636/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:https://web.archive.org/web/20160102200636/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:https://web.archive.org/web/20160102200636/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:https://web.archive.org/web/20160102200636/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:https://web.archive.org/web/20160102200636/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

Originating 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*.