Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Groovy and Grails Plans Announced at SpringOne2GX

Groovy and Grails Plans Announced at SpringOne2GX

This item in japanese

During the second technical keynote at SpringOne2GX last week Guillaume Laforge talked about plans for Groovy 2.4.x and 2.5. Perhaps the most significant is improved compiler performance with a new Abstract Syntax Tree (AST) class reader in place of using class loading tricks.

The Groovy compiler starts by compiling scripts to a Concrete Syntax Tree (CST) producing a stream of tokens which isn’t really usable by the compiler. This CST is converted into an Abstract Syntax Tree (AST) which will have a hierarchy of nodes. The CST to AST process is pluggable, giving the ability to plug in AST transformations. According to Groovy's documentation "AST transformations allow you to hook into the compilation process, modify the AST and continue the compilation process to generate regular bytecode. Compared to runtime metaprogramming, this has the advantage of making the changes visible in the class file itself (that is to say, in the bytecode)".   Working this way (compile-time metaprogramming as distinct from runtime metaprogramming) means that there is no runtime performance cost. 

Examples of ASTs in Groovy are the Singleton transformation, @Lazy for lazy evaluation, @Builder for building APIs with fluent interfaces, the Mixin transformation, Immutable AST Macros and Newify transformation.

Laforge told InfoQ that the compiler change was a contribution that came from Peter Gromov, one of the developers on IntelliJ IDEA. JetBrains wanted fast compile time of Groovy code within their IDE, and they looked at ways to improve the compilation process of the Groovy compiler, since that's what they're using too for compiling. This is the pull request for it.

Basically, for compilation, we have to read other classes, to look up class structure, method signatures, etc, to be able to compile Groovy code depending on such pre-compiled code, or JDK, etc. 

We used to be using Java's own classloaders to do that, but with the drawback that classloaders can initialize classes (running static initializers which can have side effects and be taking time to run). 

So instead of that, we've integrated that contribution which uses the ASM bytecode library to read the bytecode directly, more efficiently and without side effects.

At the time of writing Laforge didn’t have any numbers to share but stated that “there is a clear improvement inside IntelliJ IDEA, and also one for compiling the Groovy codebase itself".

As well as the compiler change, a new @MapConstructor transformation has been created to assist in the creation of map constructors in classes, which serves as a good illustration of an AST. For example the following code (based on the current 2.5 snapshot):

 import groovy.transform.*

 class Person {
     String first, last

 @CompileStatic // optional
 @MapConstructor(pre={ super(args?.first, args?.last); args = args ?: [:] }, post = { first = first?.toUpperCase() })
 class Author extends Person {
     String bookName

 assert new Author(first: 'Dierk', last: 'Koenig', bookName: 'ReGinA').toString() == 'Author(ReGinA, DIERK, Koenig)'
 assert new Author().toString() == 'Author(null, null, null)'

instructs the compiler to execute an AST transformation which adds the necessary constructor method to your class. In this example the generated code would be something like:

 public Author(java.util.Map args) {
     super(args?.first, args?.last)
     args = args ? args : [:]
     if (args.containsKey('bookName')) {
         this.bookName = args['bookName']
     first = first?.toUpperCase()

Other Groovy language changes include the @Canonical transformation becoming a meta transformation, and property validation in transformation parameters.

Elsewhere during the keynote Grails framework lead Graeme Rocher outlined plans for Grails 3.1 and beyond. Grails 3.1 GA is expected this year. It will include improvements to the Web API profile and REST applications. Support for Angular is planned, with Ember and other single page application frameworks also under consideration.

Beyond that, “In 2016 we see the potential to extend Grails far beyond the servlet container by implementing profiles for creating microservices using things like Netty, and applying asynchronous and non-blocking techniques,” Rocher stated. Other plans include extending the Grails ORM implementation GORM to support asynchronous non-blocking APIs. MongoDB 3.0, for example, has asynchronous support built into the driver, and some relational databases, such as Postgress and MySQL have emerging non-blocking data access APIs which will also be supported through GORM.

Rate this Article