3 Upgrading from Grails 2.2 2.3.8

See the light - agile, industrial strength, rapid web application development made easy

(Quick Reference) # 3 Upgrading from Grails 2.2 - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 2.3.8 # 3 Upgrading from Grails 2.2 A number of changes need to be considered when upgrading your application from Grails 2.2, some of them breaking. Here's a quick list with more detail on each item following after: New improved data binding (no Spring property editors) Much improved XSS prevention with default HTML encoding A new dependency resolution engine Must be online to fetch Grails dependencies Grails core dependencies rearranged Tomcat and Hibernate plugins independently versioned now (breaking!) Scaffolding is now a separate plugin Spock included by default Dependency injection does not work in integration tests by default Forked execution for tests Reloading in `run-app` won't work by default on upgraded apps `grails-debug` doesn't work for forked execution #### New Data Binder There is a new data binding mechanism written from the ground up to meet Grails' needs. If you wish to continue using Spring for data binding then you must set the `grails.databinding.useSpringBinder` property to `true` in `grails-app/conf/Config.groovy` #### Encoding / Escaping (XSS) Changes Grails 2.3 includes new features to help prevent XSS attacks. These are enabled by default for new applications, but older applications will require manual intervention. See the section on Cross Site Scripting (XSS) prevention for how to appropriately configure XSS prevention. #### Dependency Resolution changes Although dependency resolution using Ivy is still supported, the default for Grails 2.3 is to use Aether and the Ivy support will not be improved upon going forward. You may wish to consider using Aether instead for your existing applications by setting the following in `grails-app/conf/BuildConfig.groovy`:
    grails.project.dependency.resolver = "maven" // or ivy
If you need to authenticate to a maven repository, you will want to change the definition of that repository like so:
    mavenRepo("http://artifactory.mycompany.com/repo") {
        authentication(username: "myusername", password: "secret")
    }
#### Dependency Metadata Changes In addition, the POM and dependency metadata for Grails 2.3 has been re-arranged and cleaned up so that only direct dependencies are specified for an application and all other dependencies are inherited transitvely. This has implications to the upgrade since, for example, Ehcache is now a transitive dependency of the Hibernate plugin, whilst before it was a direct dependency. If get a compilation error related to Ehcache, it is most likely that you don't have the Hibernate plugin installed and need to directly declare the Ehcache dependency:
    compile "net.sf.ehcache:ehcache-core:2.4.6"
In addition, excludes may no longer work and may need adjusting when upgrading due to how the metadata has changed. Run the dependency-report to see the new dependency metadata and make adjustments accordingly. A common error that may occur when upgrading is:
    | Configuring classpath
    :: problems summary ::
    :::: WARNINGS
        ::::::::::::::::::::::::::::::::::::::::::::::
        ::          UNRESOLVED DEPENDENCIES         ::
        ::::::::::::::::::::::::::::::::::::::::::::::
        :: org.springframework#spring-test;3.2.2.RELEASE: configuration not found in org.springframework#spring-test;3.2.2.RELEASE: 'compile'. It was required from org.grails#grails-plugin-testing;2.3.0.BUILD-SNAPSHOT compile
        ::::::::::::::::::::::::::::::::::::::::::::::
This is caused by a plugin that depends on an old version of `spring-test` (for example the Mail plugin). To correct this run `grails dependency-report` and search for plugins that have a transitive dependency on `spring-test` and exclude them. For example:
    plugins {
      compile ':mail:1.0', {
        excludes 'spring-test'
      }
    }
However, longer term to solve problems like this we recommend that users move away from Ivy and use Aether instead for dependency resolution:
    grails.project.dependency.resolver="maven"
#### No initial offline mode with Aether Aether does not support resolving dependencies from a flat file system. This means that the jars we ship with Grails in GRAILS_HOME/lib are not used for the first resolve, but instead the jars are obtained from Maven central. After they have been obtained from Maven central then Aether operates fine offline. If however you do not have the necessary jars in your local Maven repository, then the only way to get offline execution is to enable Ivy via BuildConfig (see above). #### Changes to Core plugin versioning schemes and the Upgrade command Core plugins like `tomcat` and `hibernate` are no longer versioned the same as the Grails version, instead they are versioned according to the Tomcat and Hibernate version they target. If you are upgrading from Grails 2.2 you need to manually configure the correct Tomcat and Hibernate plugins in `BuildConfig`. The `upgrade` command will not do this for you!

    plugins {
            // plugins for the build system only
            build ':tomcat:7.0.42'        // plugins needed at runtime but not for compilation
            runtime ':hibernate:3.6.10.2'
        }
Note that the `upgrade` command will be deprecated in 2.3 and replaced with a command named `use-current-grails-version`, which will make no attempts to automatically upgrade Grails applications. #### Scaffolding moved to a plugin and rewritten If you have dynamically scaffolded controllers in your application then you will need to configure the 1.0 version of the Scaffolding plugin in BuildConfig:
    plugins {
      compile ':scaffolding:1.0.0'
    }
By default for new applications the 2.0 version of the scaffolding plugin is used, which is not backwards compatible with 1.0. #### Spock included by default You no longer need to add the Spock plugin to your projects. Simply create Spock specifications as before and they will be run as unit tests. In fact, don't install the Spock plugin, otherwise your specifications will run twice and potentially fail. This also means that the `spock` test type no longer exists. Specifications and JUnit tests run as the same type now. #### Dependency Injection for Integration Tests In order to support alternate JUnit4 test runners, Grails 2.3 no longer uses a special test runner to run tests and integration tests should no longer extend `GroovyTestCase`. This change requires that any JUnit integration tests that require dependency injection now need to be annotated with:
    @TestMixin(IntegrationTestMixin)
For Spock integration tests, extending `IntegrationSpec` also works. #### Forked Execution for Testing Tests are now by default executed in a forked JVM (although this can be disabled). One implication of this is that tests will be slower to execute when using:
    grails test-app
The reason for this is the need to load a separate JVM to execute tests. To mitigate this Grails interactive mode has been updated to load a background JVM that can be resumed. If you do:
    $ grails // load interactive mode
    $ grails -> test-app
    $ grails -> test-app
Test execution will be noticably faster and is the recommended way to run tests in Grails. On older hardware that does not include multiple cores (to run the separate JVMs) it is recommended you disable forked execution for tests to achieve faster test execution times:
    forkConfig = [maxMemory: 1024, minMemory: 64, debug: false, maxPerm: 256]
    grails.project.fork = [
       test: false, // disable forked execution for test-app
       run: forkConfig, // configure settings for the run-app JVM
       …
    ]
#### Forked Execution and the Reloading Agent In Grails 2.3 the reloading agent is no longer on the build system path unless you pass the `-reloading` flag to the `grails` command:
    grails -reloading run-app
The reason for this is that the default in Grails 2.3 and above is to load Grails application in a forked JVM and enable the agent for the forked JVM. If you do not wish to use forked JVMs then you must ensure that you run Grails with the `-reloading` flag. Alternatively, you can enable forking with the following configuration in `BuildConfig`:
    forkConfig = [maxMemory: 1024, minMemory: 64, debug: false, maxPerm: 256]
    grails.project.fork = [
       test: forkConfig, // configure settings for the test-app JVM
       run: forkConfig, // configure settings for the run-app JVM
       war: forkConfig, // configure settings for the run-war JVM
       console: forkConfig // configure settings for the Swing console JVM
    ]
#### Forked Execution and Remote Debugging The `grails-debug` command will no longer work with Grails for remote debugging sessions. The reason is the command enabled debugging for the build system JVM, but not the JVM used in forked execution. The solution to this is to use the `debug-fork` command line argument:
    grails --debug-fork run-app
Alternatively you can set the `debug` setting to `true` in `BuildConfig` and use the regular `grails` command to execute:
    forkConfig = [maxMemory: 1024, minMemory: 64, debug: true, maxPerm: 256]
    grails.project.fork = [
       run: forkConfig, // configure settings for the run-app JVM
       ...
#### Forked Execution and Functional Test plugins Some existing plugins (Cucumber plugin for example) do not work with 2.3.x forked execution because they expect the tests to be running in the same JVM as the application under tests. For example it is not possible to setup fixture / test data using GORM inside a functional test and have that data visible to the application under test since the application under test is in a separate JVM. The solution to this is to provide the necessary fixture data in the `BootStrap` of the application (only for the test environment of course). | Quick Reference (hide)