(Quick Reference)

4 Upgrading from Grails 2.3 - Reference Documentation

Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari

Version: 2.4.2

4 Upgrading from Grails 2.3

The upgrade Command

The upgrade command has been removed from Grails 2.4. The procedure for upgrading to the latest version of Grails will be detailed in the user guide from now on. Below are steps that must be taken to upgrade an application from 2.3.x to 2.4.

The set-grails-version Command

The set-grails-version command should be run to update the application's metadata to indicate which version of Grails the application is built with.

Update to latest Plugin versions

You should update your application's BuildConfig to use the latest plugins compatible with Grails 2.3. Example:

plugins {
        // plugins for the build system only
        build ':tomcat:7.0.52.1'

// plugins for the compile step compile ':scaffolding:2.1.0' compile ':cache:1.1.3' compile ':asset-pipeline:1.8.3'

// plugins needed at runtime but not for compilation runtime ':hibernate4:4.3.5.2' // or ':hibernate:3.6.10.14' runtime ':database-migration:1.4.0' runtime ':jquery:1.11.0.2' … }

You may get compilation errors or incompatibility problems with older versions of the above plugins installed.

grails-debug Script Has Been Removed

The grails-debug and grails-debug.bat scripts have been removed. To debug the build system JVM run grails -debug <command> and to debug the forked JVM run grails --debug-fork <command>.

New Command Object Data Binding Behavior

The data binding behavior for command objects has changed in Grails 2.4. Request parameter names may now be prefixed with the name of the controller action argument name that the request parameter should be bound to. For example, if a request is made to the buy action in the controller below a request parameter named buyer.name will be bound to the name property of the buyer argument and a request parameter named seller.name will be bound to the name property of the seller argument. See the Command Objects documentation for more details.

New Behavior For Domain Class Command Objects

If a command object's type is a domain class and there is no id request parameter then null will be passed into the controller action unless the HTTP request method is "POST", in which case a new instance of the domain class will be created by invoking the domain class constructor. For all of the cases where the domain class instance is non-null, data binding is only performed if the HTTP request method is "POST", "PUT" or "PATCH". See the Command Objects documentation for more details.

Nullable Command Object Properties

The behavior in Grails 2.3.x is such that constrained properties in command objects and other classes marked with @Validateable are all configured with nullable: false by default. Unconstrained properties were not configured with nullable: false. In Grails 2.4 all non-static unconstrained properties in command object classes and other classes marked with @Validateable are all configured with nullable: false.

class StoreController {
    def buy(Person buyer, Person seller) {
        // …
    }
}

class Person { String name }

If you wish to retain the old behavior, you can do so on a per-command object basis by using the @Validateable constraint explicitly and passing the nullable: true argument:

@Validateable(nullable = true)
class Person {
    String name
}

This will cause all properties to be nullable by default unless a constraint is explicitly added (similar to the behavior prior to Grails 2.4).

See the Command Objects documentation for more details.

Ajax Tags Have Been Deprecated

The formRemote, remoteField, remoteFunction and remoteLink Ajax tags have been deprecated and will be removed from a future version of Grails. Applications may provide their own Ajax tags and/or Javascript plugins may provide Ajax tags of their own.

The Spring Data Binder Has Been Deprecated

The grails.databinding.useSpringBinder config property may be set to true to tell Grails to use the Spring data binder instead of the Grails data binder. The Spring data binder has been deprecated and will be removed from a future version of Grails. It is recommended that when upgrading to Grails 2.4 that the Grails data binder be used.

The resources Plugin

As of Grails 2.4 the resources plugin has been replaced with the asset-pipeline plugin as the default resource management plugin for newly created applications. See the static resource abstraction section of the User Guide for more details. When upgrading an application to Grails 2.4 if you choose to continue using the resources plugin you will need to use version 1.2.7 or later as previous versions of the plugin are not compatible with Grails 2.4.

Static Holder Classes

The following deprecated classes have been removed from Grails 2.4.x:

  • org.codehaus.groovy.grails.commons.ApplicationHolder
  • org.codehaus.groovy.grails.commons.ConfigurationHolder
  • org.codehaus.groovy.grails.plugins.PluginManagerHolder
  • org.codehaus.groovy.grails.web.context.ServletContextHolder
  • org.codehaus.groovy.grails.compiler.support.GrailsResourceLoaderHolder

If you or any plugins you have installed are using these classes you will get a compilation error. The problem can be rectified by updating to new plugins and using grails.util.Holders instead.

If your application uses the jquery plugin you will need to update to version 1.11.0.2 or later as previous versions of the plugin made use of the ApplicationHolder class. If your application uses the resources plugin you will need to update to version 1.2.7 or later as previous versions of the plugin made use of the ConfigurationHolder class.

Changes To applicationContex.xml

The web-app/WEB-INF/applicationContext.xml file contains a bean definition for a grailsResourceLoader bean which is an instance of org.codehaus.groovy.grails.commons.GrailsResourceLoaderFactoryBean. That bean definition needs to be removed from the file. The grailsApplication bean may have the grailsResourceLoader bean injected into it as shown below.

<bean id="grailsApplication" class="org.codehaus.groovy.grails.commons.GrailsApplicationFactoryBean">
    <description>Grails application factory bean</description>
    <property name="grailsDescriptor" value="/WEB-INF/grails.xml" />
    <property name="grailsResourceLoader" ref="grailsResourceLoader" />
</bean>

The grailsApplication bean definition should be left in the file but the grailsResourceLoader bean reference should be removed as shown below.

<bean id="grailsApplication" class="org.codehaus.groovy.grails.commons.GrailsApplicationFactoryBean">
    <description>Grails application factory bean</description>
    <property name="grailsDescriptor" value="/WEB-INF/grails.xml" />
</bean>

Changes to web.xml

The Sitemesh servlet filter has been removed and the GSP layout feature is now handled by GrailsLayoutView. Applications that are using a customized web.xml should apply the customizations to a web.xml file of Grails 2.4 . This applies only to applications that have used the "install-templates" to install template files in src/templates folder of the application. It's recommended to rename src/templates to a different name and use a diff tool to apply the possible application specific customizations to the files created with Grails 2.4 install-templates command.

Data Binding Changes

Prior to Grails 2.4 when data binding was performed with the params object in a controller, if the request contained a body the body would be parsed and used for data binding instead of the params object. In Grails 2.4 this behavior has changed so that if binding is initiated with params, the binding will always be done with the params object, without regard to whether or not the request has a body. If binding is done with the request object, if the request has a body then the body will be parsed and used for data binding, otherwise the request parameters will be used for data binding.

class SomeController {

def someAction() { // Prior to Grails 2.4 if the request contains a body // then obj1 will be populated with values parsed from // the body instead of with values in params.

// With Grails 2.4 obj1 will be pouplated with values // in params. def obj1 = new SomeDomainClass(params)

// the same is true for the following def obj2 = new SomeDomainClass() obj2.properties = params }

def someOtherAction() { // If the request contains a body then obj1 will be // populated with values parsed from the body, otherwise // obj1 will be populated with the request parameters.

// This is not a new change in behavior. def obj1 = new SomeDomainClass() obj1.properties = request } }

There is one release in the 2.3.x chain which has the 2.4 behavior described above and that is Grails 2.3.8. None of the 2.3.x releases before or after 2.3.8 have this behavior.

The allowedMethods Property And Unit Tests

The unit testing environment now respects the allowedMethods property in controllers. Prior to Grails 2.4 a unit test which accessed a controller action which is supposed to be restricted to certain request methods could have skipped the step of setting the request method in the unit test because the allowedMethods property was ignored by the unit test. As of Grails 2.4 if a controller action is limited to be accessed with certain request methods, the unit test must be constructed to deal with that.

// grails-app/controllers/com/demo/DemoController.groovypackage com.demo

class DemoController {

static allowedMethods = [save: 'POST', update: 'PUT', delete: 'DELETE']

def save() { render 'Save was successful!' }

// … }

// test/unit/com/demo/DemoControllerSpec.groovy
package com.demo

import grails.test.mixin.TestFor import spock.lang.Specification import static javax.servlet.http.HttpServletResponse.*

@TestFor(DemoController) class DemoControllerSpec extends Specification {

void "test a valid request method"() { when: request.method = 'POST' controller.save()

then: response.status == SC_OK response.text == 'Save was successful!' }

void "test an invalid request method"() { when: request.method = 'DELETE' controller.save()

then: response.status == SC_METHOD_NOT_ALLOWED } }

scanning for JSP taglibs has to be configured, no JSTL default dependency

JSP taglib tld files aren't scanned by default any more. This must be configured with the grails.gsp.tldScanPattern setting. It accepts a comma separated String value. Spring's PathMatchingResourcePatternResolver is used to resolve the patterns.

You can get the previous behaviour by adding this setting to Config.groovy:

grails.gsp.tldScanPattern='classpath*:/META-INF/*.tld,/WEB-INF/tld/*.tld'

JSTL standard library is no more added as a dependency. In case you are using JSTL, you should also add these dependencies:

runtime 'javax.servlet:jstl:1.1.2'
        runtime 'taglibs:standard:1.1.2'