Migrating to Grails 2.3
I just migrated a grails 2.2 app to grails 2.3. Of course I didn’t read the doc in advance — I (almost) never do. Rather than read the doc, I created a project with the old version of grails and another project for grails 2.3. A directory diff of the two shows where the changes are. With grails 2.3 the biggest changes are in BuildConfig.groovy
and Config.groovy
. That’s not too surprising and it’s pretty easy to clean up the changes and migrate the files in my existing app. After that the app compiled but many of the tests failed: I uncovered a few problems while trying to unwind it all. Here are the highlights…
Forked Execution (not quite ready)
Jumping back and forth between testing the app in the interactive mode and from a single command `grails test-app` is not too smooth. At one point I ended up with a forked jvm process that just kept on running and wouldn’t die until I killed the shell. Not sure how I got into that state, but IMHO running tests “faster” is never worth having to worry about zombie processes/forks that may or may not auto-reload changes. And killing the process by itself wasn’t enough of a kick in the a** to grails to set things right. I hope it’s better in 2.3.1.
The good news: if you struggle with forked JVMs it’s easy to disable in BuildConfig.groovy
…
grails.project.fork = [ test: false, run: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256], war: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256], console: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256], ]
Automatic Class Reloading Is No Longer The Default!
One of the best features of grails is the auto reload of classes when running the app. But in grails 2.3 auto-reloading is NOT ENABLED by default. WTF? If you want auto reload changes you’ve got to add the -reloading
flag to the command…
grails -reloading run-app
This includes running grails in interactive mode. If you don’t start up with -reloading
the interactive mode won’t pick up any class changes. Don’t know why they made this change (maybe something to do with the forked daemon processes?)
You can also turn on loading by default in BuildConfig.groovy
with
grails.reload.enabled = true
Spock Now Included As Part Of Grails
Not only is spock included as part of grails, it is also the default test runner. This is great news and if you weren’t already using spock now’s the time to switch (Why Spock?.)
But Don’t Forget to Remove Old Dependencies on Spock
Simply migrating a 2.2.2 grails application that already used the spock plugin to 2.3 will end up double running the spec tests. Here’s console output for running a single test class with one test method…
> grails test-app unit: DomainTestUtilSpec | Completed 1 unit test, 0 failed in 0m 0s | Running 1 spock test... 1 of 1 --Output from stringWithLength-- | Error --Output from stringWithLength-- | Completed 1 spock test, 0 failed in 0m 0s | Tests PASSED - view reports in [snip]/target/test-reports >
The solution is to remove all spock references from BuildConfig.groovy
. If you don’t, tests will be run twice. Why? Spock is now included as a built in test runner as part of grails 2.3. If you migrate an app and leave the spock plugin then the default spock test runner will run the test, and then the plugin will too.
Maybe that’s not so bad but it sure would be nice to get some sort of warning about no longer needing the spock plugin in BuildConfig.groovy
.
Spock Integration Tests
In grails 2.2.x spock (*Spec) tests extended grails.plugin.spock.IntegrationSpec
but with spock’s inclusion as part of grails that class is no longer present. In 2.3 simply extend spock.lang.Specification
(just like a unit test.)
Nullable Constraints
"The default behavior is such that a blank string will not validate for nullable: false since the data binder will convert blank strings to null. This includes empty strings and blank strings."
Kind of a big change from 2.2! You can configure this behavior in Config.groovy with
grails.databinding.convertEmptyStringsToNull=false
But I choose to change the domain objects constraints and refactor the tests to match.
Reading the Doc…
Once over the hump its time to incorporate all the new features available in grails 2.3: grails.org/doc/…whatsNew23.
Are you sure about the reloading turned off by default? I started a new app in 2.3 and it picks up changes when run with grails run-app. Nothing in my BuildConfig about reload.enabled, and no command line options. Not sure about interactive mode though, I haven’t tested that.
Todd, Yes I’m sure. (See the “Forked Execution and the Reloading Agent” secgion on http://grails.org/doc/2.3.x/guide/upgradingFromPreviousVersionsOfGrails.html.)
You may only notice that reloading is off if you disable forked execution. If you’re have any luck with forked execution enabled I’d love to here what your configuration is. I couldn’t get anywhere with forked exec on OS X 10.8.5. So I had to disable forking and enable reloading before all the grails goodness worked as expected.
I had the same experience with the forked execution stuff.. Imho it’s just not production ready and I ended up disabling it.
The grails.plugin.spock.IntegrationSpec is gone, but 2.3 has grails.test.spock.IntegrationSpec. Are you sure that it should not be used?
Good point J. David. Thanks for bringing it to my attention.
I just refactored a set of integration tests to use the g.t.s.IntegrationSpec and I get the same results as using s.l.Specification. These are old tests that have migrated up from an app that was originally grails 1.3.*. Looking back at them again I should rework them to be more annotation based — maybe if I do that I’ll see some differences between Specification and IntegrationSpec.
An update after starting a new project with 2.3.5…
For my latest project we’re using 2.3.5 “out of the box” and so far it is much better! The only glitch I still see is some line-overwriting on the console when using the command line.
The forked execution and class reloading problems I saw with 2.3.(N<5) are resolved.