Groovy 1.8 release notes
The 1.8 release of Groovy comes with many new features that greatly enhance
These features have undergone the Groovy developer process with formal descriptions, discussion, and voting (GEP - Groovy Enhancement Proposal) for core parts and less formal developer discussions and JIRA voting for additional parts.
Our goal has stayed the same, though: to give the Java developer a tool that makes him more productive, allows him to achieve his goals faster and with a smaller margin of error, and extend the scalability of the Java platform from full-blown enterprise projects to everyday "getting things done" tasks.
Command chains for nicer Domain-Specific Languages
Thanks to its flexible syntax and its compile-time and runtime metaprogramming capabilities, Groovy is well known for its Domain-Specific Language capabilities. However, we felt that we could improve upon the syntax further by removing additional punctuation symbols when users chain method calls. This allows DSL implementors to develop command descriptions that read almost like 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 parentheses-free method calls, requiring neither parentheses around arguments, nor dots between the chained calls. The general idea is that a call like
It is also possible to use methods in the chain which take no arguments, but in that 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 the much wider range of DSLs which can now be written in Groovy. 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 command chain based 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):
Groovy's flexible metaprogramming model involves numerous decision points when making method calls or accessing properties to determine whether any metaprogamming hooks are being utilized. During complex expression calculations, such decision points involved identical checks being executed numerous times. Recent performance improvements allow some of these checks to be bypassed during an expression calculation once certain initial assumptions have been checked. Basically if certain preconditions hold, some streamlining can take place.
Groovy 1.8.0 contains two main streams of optimization work:
Those two areas of optimization are only the beginning of further similar improvements. Upcoming versions of the Groovy 1.8.x branch will see more optimizations coming. In particular, primitive types other than integers should be expected to be supported shortly.
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
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 a key 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! As an example, the GContracts project, which brings the "Design by Contract" paradigm to Groovy makes heavy use of annotation parameters to allow preconditions, postconditions and invariants to be declared.
Closure functional flavors
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.
When writing recursive algorithms, you may be getting the infamous stack overflow exceptions, as the stack starts to have a too high depth of recursive calls. An approach that helps in those situations is by using Closures and their new trampoline capability.
Closures are wrapped in a
Here's an example of the use of
Another improvement to Closures is the ability to memoize the outcome of previous (ideally side-effect free) invocations of your Closures. The return values for a given set of Closure parameter values are kept in a cache, for those memoized Closures. That way, if you have an expensive computation to make that takes seconds, you can put the return value in cache, so that the next execution with the same parameter will return the same result – again, we assume results of an invocation are the same given the same set of parameter values.
There are three forms of memoize functions:
Let's illustrate that:
Currying improvements have also been backported to recent releases of Groovy 1.7, but it's worth outlining here for reference. Currying used to be done only from left to right, but it's also possible to do it from right to left, or from a given index, as the following examples demonstrate:
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.
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.
Parsing JSON data structures is one thing, but we should also be able to produce JSON content just like we create markup with the
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 structure, 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
The Groovy compiler reads the source code, builds and Abstract Syntax Tree (AST) from it, and then puts the AST into bytecode. With AST transformations, the programmer can hook into this process. A general description of this process, an exhaustive description of all available transformations, and a guide of how to write you own ones can be found for example in Groovy in Action, 2nd Edition (MEAP), chapter 9.
Below is a list of all new transformations that come with Groovy 1.8. They save you from writing repetitive code and help avoiding common errors.
You can annotate your classes with the @Log transformation to automatically inject a logger in your Groovy classes, under the
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
Another particularity of these logger AST transformations is that they take care of wrapping and safe-guarding logger calls with the usual
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
More concretely, you'll be able to do as follows:
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
See the Javadoc for
Which will create a class of the following form:
Controlling the execution of your code
When integrating user-provided Groovy scripts and classes in your Java application, you may be worried about code that would eat all your CPU with infinite loops, or that call methods like
Groovy 1.8 introduces three transformations for those purposes, as we shall see in the following sections. By default, the three transformations add some checks in at the beginning of each method body, and each closure body, to check whether a condition of interruption is met or not.
Note that those transformations are local (triggered by an annotation). If you want to apply them transparently, so that the annotation doesn't show up, I encourage you to have a look at the
Cédric Champeau, our most recent Groovy committer, who implemented those features, has a very nice blog post covering those code interruption transformations.
You don't need to write checks in your scripts for whether the current thread of execution has been interrupted or not, by default, the transformation will add those checks for you for scripts and classes, at the beginning of each method body and closure body:
You can specify a
In addition to the previous annotation parameters we mentioned for
An example of
You can imagine defining any kind of condition: on counters, on resource availability, on resource usage, and more.
Provides your classes with a default
And here's another example using a few more options:
Provides your classes with
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
You will find a great write-up on @Canonical, @ToString, @EqualsAndHashCode and @TupleConstructor on John Prystash's weblog.
Sometimes, when you want to subclass certain classes, you also need to override all the constructors of the parent, even if only to call the super constructor. Such a case happens for instance when you define your own exceptions, you want your exceptions to also have the constructors taking messages and throwable as parameters. But instead of writing this kind of boilerplate code each time for your exceptions:
Simply use the @InheritConstructors transformation which takes care of overriding the base constructors for you:
@WithReadLock and @WithWriteLock
Those two transformations, combined together, simplify the usage of
More concretely, with an example, the following:
Will generate code as follows:
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.
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
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 when you wish to embed content that may naturally contains slashes or backslashes and you don't want to have to rework the content to include all of the necessary escaping. Some examples are shown below:
The compilation of Groovy code can be configured through the
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
(G)String to Enum coercion
Given a String or a GString, you can coerce it to Enum values bearing the same name, as the sample below presents:
Maps support isCase()
Maps now support
Shorter notation for @GrabResolver
When you need to specify a special grab resolver, for when the artifacts you need are not stored in Maven central, you could use:
Groovy 1.8 adds a shorter syntax as well:
Compact form for optional Grab attributes
The compact form for grab which allows the artifact information to be represented as a string now supports specifying additional attributes. As an example, the following script will download the commons-io jar and the corresponding javadoc jar before using one of the commons-io methods.
Storing AST node metadata
When developing AST transformations, and particularly when using a visitor to navigate the AST nodes, it is sometimes tricky to keep track of information as you visit the tree, or if a combination of transforms need to be sharing some context. The
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
Support for begin() / end() methods when processing files line by line with the groovy command
A feature found in other scripting languages like Perl or Awk is to be able to have a begin / end method when processing a file line by line. The groovy command supports this mode of operation, but didn't support the begin / end methods. (this feature is actually going to be available in 1.7.11 and 1.8.1, but time ran short for inclusion in the 1.8 final release)
More concretely, if you have a text file named dummy.txt, and you want to count the number of lines it contains, you could do this on the command-line:
You are viewing an old version of this page. View the current version. Compare with Current · View Page History