Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 46 Next »

Groovy 1.8 release notes


This page is a placeholder for the upcoming release notes for the final release of Groovy 1.8. This page is neither complete nor even finished!

Command chains for nicer Domain-Specific Languages

Groovy is well known for its Domain-Specific Language capabilities, thanks to its flexible syntax, and its compile-time and runtime metaprogramming capabilities. However, we felt that we could improve upon the syntax to get rid of even more punctuation when users chain method calls, to allow DSL implementors to develop language closer to natural sentences.

Before Groovy 1.8, we could omit parentheses around the arguments of a method call for top level statements. But we couldn't chain method calls. The new "command chain" feature allows us to chain such parenthese-free method calls, without requiring neither parentheses around arguments, nor dots between the chained calls. The general idea is that a call like a b c d will actually be equivalent to a(b).c(d). This is also working with multiple arguments, closure arguments, and even named arguments. Furthermore, such command chains can also appear on the right-hand side of assignments. Let's have a look at some examples of the kind of syntaxes that this allows:

It is also possible to use methods, in the chain, which don't take arguments, but in the case, the parentheses are needed:

If your command chain contains an odd number of elements, the chain will be composed of method / arguments, and will finish by a final property access:

This new command chain approach opens up interesting possibilities in terms of DSLs that are now possible to be written. This new feature has been developed thanks to the Google Summer of Code program, where our student, Lidia, helped us modify the Groovy Antlr grammar to extend top-level statements to accept that command chain syntax.

The above examples illustrate using a GEP-3 DSL but not how to create one. You will be able to find some further examples of "command chains" on the Groovy Web Console but to illustrate creating such a DSL, we will show one example - first using maps and Closures:

Or if you prefer Japanese and a metaprogramming style (see here for more details):

Performance improvements

In general the goal of these improvements is to bypass the MOP where allowed and possible without altering the original MOP too much.

Groovy 1.8.0 contains several integer based optimizations for basic operations like plus, minus, multiply, increment, decrement and comparisons. This versiondoesn't support the mixed usage of different types and then falls back to the classical way of performing the operation.

This version also contains an optimization for direct method calls. Such a method call is done directly if it is done on "this" and if the argument types are a direct match with the parameter types of the method we may call. Since this is an operation that does not behave too well with a method call logic based on runtime types we select only methods where the primtive types match, the parameter types are final or for methods that take no arguments. Currently methods with variable arguments are not matched in general, unless a fitting array is used for the method call.

Those two optimizations are only the beginning of further similar improvements related to primitive type handline. Upcoming versions of the Groovy 1.8.x branch will see more optimizations coming.

GPars bundled within the Groovy distribution

The GPars project offers developers new intuitive and safe ways to handle Java or Groovy tasks concurrently, asynchronously, and distributed by utilizing the power of the Java platform and the flexibility of the Groovy language. Groovy 1.8 now bundles GPars 0.11 in the libraries of the Groovy installation, so that you can leverage all the features of the library for your concurrent, asynchronous and parallel needs.

To learn more about GPars, head over to the GPars website, or read the detailed online user guide.

Closure enhancements

Closures are a central and essential piece of the Groovy programming language, and are used in various ways throughout the Groovy APIs. In Groovy 1.8, we introduce the ability to use closures as annotation parameters. Closures are also part of what gives Groovy its functional flavor.

Closure annotation parameters

In Java, there's a limited set of types you can use as annotation parameters (String, primitives, annotations, classes, and arrays of these). But in Groovy 1.8, we're going further and let you use closures as annotation parameters – which are actually transformed into a class parameter for compatibility reasons.

Closure annotation parameters open up some interesting possibilities for framework authors! And for instance, this is the approach taken by the GContracts project, which brings the "Design by Contract" paradigm to Groovy.

Closure functional flavors

Closure composition

If you recall your math lessons, function composition may be a concept you're familiar with. And in turn, closure composition is about that: the ability to compose closures together to form a new closure which chains the call of those closures. Here's an example of composition in action:

To see more examples of closure composition and reverse composition, please have a look at our test case.

Closure memoization

Closure trampoline

Native JSON support

With the ubiquity of JSON as an interchange format for our applications, it is natural that Groovy added support for JSON, in a similar fashion as the support Groovy's always had with XML. So Groovy 1.8 introduces a Json builder and parser.

JSON parser

A JsonSlurper class allows you to parse JSON payloads, and access the nested Map and List data structures representing that content. JSON objects and arrays are indeed simply represented as Maps and Lists, giving you access to all the GPath expression benefits (subscript/property notation, find/findAll/each/inject/groupBy/etc.). Here's an example showing how to find all the recent commit messages on the Grails project:

If you want to see some more examples of the usage of the JSON parser, you can have a look at the JsonSlurper tests in our code base.

JSON builder

Parsing JSON data structures is one thing, but we should also be able to produce JSON content just like we create markup with the MarkupBuilder. The following example:

Will create the JSON output:

You can find some more usages of the JSON builder in our JsonBuilder tests.

Pretty printing JSON content

When given a JSON data sturcture, you may wish to pretty-print it, so that you can more easily inspect it, with a more friendly layout. So for instance, if you want to pretty print the result of the previous example, you could do:

Which would result in the following pretty-printed output:

New AST Transformations


You can annotate your classes with the @Log transformation to automatically inject a logger in your Groovy classes, under the log property. Four kind of loggers are actually available:

  • @Log for java.util.logging
  • @Commons for Commons-Logging
  • @Log4j for Log4J
  • @Slf4j for SLF4J

Here's a sample usage of the @Log transformation:

You can change the name of the logger by specifying a different name, for instance with @Log('myLoggerName').

Another particularity of these logger AST transformations is that they take care of wrapping and safe-guarding logger calls with the usual isSomeLevelEnabled() calls. So when you write 'Car constructed', the generated code is actually equivalent to:


When defining variables in a script, those variables are actually local to the script's run method, so they are not accessible from other methods of the script. A usual approach to that problem has been to store variables in the binding, by not def'ining those variables and by just assigning them a value. Fortunately, the @Field transformation provides a better alternative: by annotating your variables in your script with this annotation, the annotated variable will become a private field of the script class.

More concretely, you'll be able to do as follows:

@PackageScope enhancements

The @PackageScope annotation can be placed on classes, methods or fields and is used for turning off Groovy's visibility conventions and reverting back to Java conventions. This ability is usually only needed when using 3rd party libraries which rely on the package scope visibility. When adding the @PackageScope annotation to a field, Groovy will assign package scope access to the field rather than automatically treating it as a property (and adding setters/getters). Annotating a class or method with @PackageScope will cause Groovy to revert to Java's convention of leaving the class/method as package scoped rather than automatically promoting it to public scope. The class variant can also take one or more parameters to allow nested setting of visibility of attributes within the class - see the Javadoc for more details. Recent versions of Groovy 1.7 have had a more limited version of this annotation.


The @AutoClone annotation is placed on classes which you want to be Cloneable. The annotation instructs the compiler to execute an AST transformation which adds a public clone() method and adds Cloneable to the classes implements list of interfaces. Because the JVM doesn't have a one-size fits all cloning strategy, several customizations exist for the cloning implementation:

  • By default, the clone() method will call super.clone() before calling clone() on each Cloneable property of the class. Example usage:
    Which will create a class of the following form:
  • Another popular cloning strategy is known as the copy constructor pattern. If any of your fields are final and Cloneable you should set style=COPY_CONSTRUCTOR which will then use the copy constructor pattern.
  • As a final alternative, if your class already implements the Serializable or Externalizable interface, you might like to set style=SERIALIZATION which will then use serialization to do the cloning.

See the Javadoc for AutoClone for further details.


The @AutoExternalizable class annotation is used to assist in the creation of Externalizable classes. The annotation instructs the compiler to execute an AST transformation which adds writeExternal() and readExternal() methods to a class and adds Externalizable to the interfaces which the class implements. The writeExternal() method writes each property (or field) for the class while the readExternal() method will read each one back in the same order. Properties or fields marked as transient are ignored. Example usage:

Which will create a class of the following form:

Controlling the execution of your code





Provides your classes with a default toString() method which prints out the values of the class' properties (and optionally the property names and optionally fields). A basic example is here:

And here's another example using a few more options:


Provides your classes with equals() and hashCode() methods based on the values of the class' properties (and optionally fields and optionally super class values for equals() and hashCode()).


Provides a tuple (ordered) constructor. For POGOs (plain old Groovy objects), this will be in addition to Groovy's default "named-arg" constructor.


Allows you to combine @ToString, @EqualsAndHashCode and @TupleConstructor. For those familiar with Groovy's @Immutable transform, this provides similar features but for mutable objects.

By default, @Canonical gives you vanilla versions for each of the combined annotations. If you want to use any of the special features that the individual annotations give you, simply include the individual annotation as well.

You will find a great write-up on @Canonical, @ToString, @EqualsAndHashCode and @TupleConstructor on John Prystash weblog.



Alignments with JDK 7

Groovy 1.9 will be the version which will align as much as possible with the upcoming JDK 7, so beyond those aspects already covered in Groovy (like strings in switch and others), most of those "Project Coin" proposals will be in 1.9, except the "diamond operator" which was added in 1.8, as explained in the following paragraph.

Diamond operator

Java 7 will introduce the "diamond" operator in generics type information, so that you can avoid the usual repetition of the parameterized types. Groovy decided to adopt the notation before JDK 7 is actually released. So instead of writing:

You can "omit" the parameterized types and just use the pointy brackets, which now look like a diamond:

New DGM methods

  • count Closure variants
  • countBy
  • plus variants specifying a starting index
  • equals for Sets and Maps now do flexible numeric comparisons (on values for Maps)
  • toSet for primitive arrays, Strings and Collections


Slashy strings

Slashy strings are now multi-line:

This is particularly useful for multi-line regexs when using the regex free-spacing comment style (though you would still need to escape slashes):

Dollar slashy strings

A new string notation has been introduced: the "dollar slashy" string. This is a multi-line GString similar to the slashy string, but with slightly different escaping rules. You are no longer required to escape slash (with a preceding backslash) but you can use '$$' to escape a '$' or '$/' to escape a slash if needed. Here's an example of its usage:

This form of string is typically used only in places where regular escaping can be ugly, e.g. XML fragments with backslashes and interpolation in use:

Or windows pathnames containing a slash at the end:

Or multi-line regexs when using the regex free-spacing comment style (particularly ones which contain slashes):

Compilation customizers

The compilation of Groovy code can be configured through the CompilerConfiguration class, for example for setting the encoding of your sources, the base script class, the recompilation parameters, etc). CompilerConfiguration now has a new option for setting compilation customizers (belonging to the org.codehaus.groovy.control.customizers package). Those customizers allow to customize the compilation process in three ways:

  • adding default imports with the ImportCustomizer: so you don't have to always add the same imports all over again
  • securing your scripts and classes with the SecureASTCustomizer: by allowing/disallowing certain classes, or special AST nodes (Abstract Syntax Tree), filtering imports, you can secure your scripts to avoid malicious code or code that would go beyond the limits of what the code should be allowed to do.
  • applying AST transformations with the ASTTransformationCustomizer: lets you apply transformations to all the class nodes of your compilation unit.

For example, if you want to apply the @Log transformation to all the classes and scripts, you could do:

This will log the two messages, the one from the script, and the one from the Car class constructor, through java.util.logging. No need to apply the @Log transformation manually to both the script and the class: the transformation is applied to all class nodes transparently. This mechanism can also be used for adding global transformations, just for the classes and scripts that you compile, instead of those global transformations being applied to all scripts and classes globally.

If you want to add some default imports (single import, static import, star import, star static imports, and also aliased imports and static imports), you can use the import customizer as follows:

When you want to evaluate Math expressions, you don't need anymore to use the import static java.lang.Math.* star static import to import all the Math constants and static functions.

Ability to customize the GroovyDoc templates

GroovyDoc uses hard-coded templates to create the JavaDoc for your Groovy classes. Three templates are used: top-level templates, a package-level template, a class template. If you want to customize these templates, you can subclass the Groovydoc Ant task and override the getDocTemplates(), getPackageTemplates(), and getClassTemplates() methods pointing at your own templates. Then you can use your custom GroovyDoc Ant task in lieu of Groovy's original one.

  • No labels