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
Theupgrade
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'sBuildConfig
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' … }
grails-debug Script Has Been Removed
Thegrails-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 thebuy
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 noid
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 withnullable: 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
}
nullable: true
argument:@Validateable(nullable = true) class Person { String name }
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
Thegrails.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 theresources
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
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 theApplicationHolder
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 theConfigurationHolder
class.
Changes To applicationContex.xml
Theweb-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>
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 theparams
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.democlass DemoController { static allowedMethods = [save: 'POST', update: 'PUT', delete: 'DELETE'] def save() {
render 'Save was successful!'
} // …
}
// test/unit/com/demo/DemoControllerSpec.groovy package com.demoimport 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 thegrails.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'
runtime 'javax.servlet:jstl:1.1.2' runtime 'taglibs:standard:1.1.2'