GRAILS.IO Avatar

Excellent Building Google Calendar in Grails Tutorial Series

Craig Burke has put together an excellent series demonstrating building a Google Calendar type application using Grails and jQuery.

The MongoDB NoSQL Database Blog: Groovy on Grails in the Land of MongoDB

mongodb:

Groovy and Grails’ speed and simplicity are a perfect match to the flexibility and power of MongoDB. Dozens of plugins and libraries connect these two together, making it a breeze to get Grooving with MongoDB.

Using Grails with MongoDB

For the purpose of this post, let’s pretend we’re writing a…

Grails 2.0.1 Available…

Today we put out Grails 2.0.1, we’ve been keeping our eyes open for folks who are having trouble upgrading and trying to proactively fix the issues that people encounter during an upgrade.

Grails 2.0.1 is the result of that work and includes over 80 bug fixes and improvements, hopefully paving the way for more folks to upgrade. 

Let us know if you’re having trouble and we’ll prioritize the issue.

Chronic iMac Wifi Kernel Panics in Lion

Dear Apple, I want to like Lion I really do, but as of today I cannot recommend anyone upgrading to it if you own an iMac (mid 2011). I personally am going to downgrade to Snow Leopard at the next available opportunity.

There are chronic Wifi related kernels panics that are seemingly going unaddressed by Apple. I personally have 3 or 4 kernel panics per day (using 10.7.3). There are multiple threads on the topic in the Apple support forums. Some schools have dozens of machines impacted. This is not an isolated problem. Some have indicated that replacing the Lion Wifi driver with the Snow Leopard one resolves the problem. Not for me.

It seems the only way to have a stable iMac system with Lion is to disable Wifi. Completely unacceptable that, considering the issue doesn’t occur if I run Windows in Bootcamp and didn’t occur with Snow Leopard.

Apple please, sort it out. Rant over.

O'Reilly: Mastering Grails 101 Video

Check out this 3 hour+ screencast of starting out with Grails 2.0 by the excellent duo Tim Berglund and Matthew McCullough. Nice to see some professional level screencasts out there.

Call for testing of existing Maven plugin

If anybody out there has the time please test out Maven plugin for Grails 2.0 and report back any issues. Instructions for setup can be found here.

Nice installing Grails 2.0 on OS X screencast for beginners. See also Installing Grails 2.0 on Windows for those less fortunate.

Functional testing Grails core with Gradle, Spock and Geb

Today I pushed a new functional test suite for Grails that is based on Gradle, Spock and Geb.

I have been relatively frustrated with our existing functional test suite and wanted to modernize it to take advantage of all the latest innovations happening in the Groovy testing community.

The requirements fulfilled by the new test suite are as follows:

  • Allow tests to be created in a standard Gradle structure 
  • Allow tests to be run from the IDE
  • Enable easy scripting of the Grails command line
  • Enable easy web function testing of the running application

An example of what I came up with can be seen below:


class RunAppSpec extends BaseSpec {
    void "Test run-app starts correctly"() {
        given:"A new project"
            grails {
                createApp "test"
                runApp()
            }

        when:"The home page is requested"
            go ""
        then:"The Grails welcome page is shown"
            title == "Welcome to Grails"
    }
}

As you can see the Grails command line can be easily scripted with the grails block. Then testing of web UIs is left to Geb’s DSL.

Hopefully this will also make it easier for folks to contribute functional tests. Please feel free to fork the repository and send us a pull request!

Lessons learnt developing Groovy AST transformations

Updated 17/01/2012: Info on handling exceptions 

During the development of Grails 2.0 we shifted a significant amount of meta-programming logic to Groovy AST transformations. 

The advantages of AST transformations are several. More flexible DSLs can be created, you don’t pay a runtime startup cost to use these DSLs and as a framework developer you can inline method calls where necessary.

Having said that Groovy AST development has its dark sides and below I’m going to list some lessons learnt developing AST transforms:

1. Avoid Global Transforms

Global AST transformations have their place, but they also have limitations. Their order is undetermined, you cannot have dependencies between transformations and they tend to be more difficult to debug.

We ended up rolling our own equivalent to global transforms using Spring class path scanning and other the Spring Ordered interface to control ordering.

2. Write Utility Methods

AST transformation code can be very repetitive. We ended up coming up with GrailsASTUtils as well as a series of base classes to make common transforms easy. Things like adding a method that delegates to property (like Groovy’s @Delegate) or the equivalent of Java reflection APIs for introspecting ClassNode instances are available via GrailsASTUtils.

We also wrote an alternative to Groovy’s @Delegate called ApiDelegate that allows you to get a reference to the delegating instance and honors any annotations found in methods of the delegate.

3. Don’t Reuse AST nodes

Say you have a reference to a ClassNode instance obtained by inspecting the AST you’re transforming. Do NOT under any circumstances use this ClassNode to add a new method or property to the class being transformed. Doing stuff like:

 
  MethodNode fooMethod = classNode.getMethod("foo", new Parameter[0]) 
  classNode.addMethod( new MethodNode("newMethod",                                       
                                       Modifier.PUBLIC, 
                                       fooMethod.getReturnType(),                                       
                                       new Parameter[0],                                      
                                       new ClassNode[0],
                                       methodBody);  ) )

Where you are reusing the ClassNode returned from getReturnType() is very dangerous and lead to all sorts of generics related errors. Always create a new ClassNode reference from an existing one using ClassHelper:

 
  MethodNode fooMethod = classNode.getMethod("foo", new Parameter[0]) 
  classNode.addMethod( new MethodNode("newMethod",                                       
                                       Modifier.PUBLIC, 
                                       ClassHelper.make(fooMethod.getReturnType().getName()),                                       
                                       new Parameter[0],                                      
                                       new ClassNode[0],
                                       methodBody);  ) )

The above using of ClassHelper.make(..) will save you loads of time, trust me.

4. Get comfortable with byte code and decompilers

Nobody said writing AST transformations was for the feint hearted and if you’re going to write any non-trivial transform you’ll need to get comfortable with using javap and a Java decompiler just in case something goes wrong in the byte code generation phase.

I recommend JD-GUI for byte code decompilation and easy viewing. Whilst javap is fine for seeing the raw byte code.

5. Never throw Exceptions from an AST transform

The Groovy compiler really doesn’t like it if you throw an exception from an AST transform. It also results in ugly errors to the user of your transform.

The proper way to report an error is via the SourceUnit which has an errorCollector property:

 
String messageText = "You can only negate a binary expressions in queries."
Token token = Token.newString(
                       expression.getText(),
                       expression.getLineNumber(), 
                       expression.getColumnNumber())
LocatedMessage message = new LocatedMessage(messageText, token, sourceUnit)
sourceUnit
   .getErrorCollector()
   .addError(message);

This will properly report a compilation error to the user. Notice too how you can pass information about the current expression node (line number, column number etc.) so that the compiler reports the location of the error nicely to the user.

Example AST Transforms in Grails

Finally, I thought I would list some of the AST transforms and what they do in Grails if you wish to see some examples in action: