3 Upgrading from previous versions of Grails 3.1.10

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

(Quick Reference) # 3 Upgrading from previous versions of Grails - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 3.1.10 ## Table of Contents # 3 Upgrading from previous versions of Grails Grails 3.0 is a complete ground up rewrite of Grails and introduces new concepts and components for many parts of the framework. When upgrading an application or plugin from Grails 3.0 there are many areas to consider including: Removal of dynamic scaffolding from Grails 3.0.0 till 3.0.4 when it was re-introduced Removal of before and after interceptors Project structure differences File location differences Configuration differences Package name differences Legacy Gant Scripts Gradle Build System Changes to Plugins Source vs Binary Plugins The best approach to take when upgrading a plugin or application (and if your application is using several plugins the plugins will need upgrading first) is to create a new Grails 3.0 application of the same name and copy the source files into the correct locations in the new application. ### Removal of before and after interceptors Before and after interceptors were removed. So all `beforeInterceptor` and `afterInterceptor` need to be replaced by Stand alone interceptors. #### File Location Differences The location of certain files have changed or been replaced with other files in Grails 3.0. The following table lists old default locations and their respective new locations:
Old Location | New Location | Description
--- | --- | ---
`grails-app/conf/BuildConfig.groovy` | `build.gradle` | Build time configuration is now defined in a Gradle build file
`grails-app/conf/Config.groovy` | `grails-app/conf/application.groovy` | Renamed for consistency with Spring Boot
`grails-app/conf/UrlMappings.groovy` | `grails-app/controllers/UrlMappings.groovy` | Moved since grails-app/conf is not a source directory anymore
`grails-app/conf/BootStrap.groovy` | `grails-app/init/BootStrap.groovy` | Moved since grails-app/conf is not a source directory anymore
`scripts` | `src/main/scripts` | Moved for consistency with Gradle
`src/groovy` | `src/main/groovy` | Moved for consistency with Gradle
`src/java` | `src/main/groovy` | Moved for consistency with Gradle
`test/unit` | `src/test/groovy` | Moved for consistency with Gradle
`test/integration` | `src/integration-test/groovy` | Moved for consistency with Gradle
`web-app` | `src/main/webapp` or `src/main/resources/` | Moved for consistency with Gradle
`*GrailsPlugin.groovy` | `src/main/groovy` | The plugin descriptor moved to a source directory
`src/main/resources/public` is recommended as `src/main/webapp` only gets included in WAR packaging but not in JAR packaging. For plugins the plugin descriptor (a Groovy file ending with "GrailsPlugin") which was previously located in the root of the plugin directory should be moved to the `src/main/groovy` directory under an appropriate package. #### New Files Not Present in Grails 2.x The reason it is best to create a new application and copy your original sources to it is because there are a number of new files that are not present in Grails 2.x by default. These include:
File | Description
--- | ---
`build.gradle` | The Gradle build descriptor located in the root of the project
`gradle.properties` | Properties file defining the Grails and Gradle versions
`grails-app/conf/logback.groovy` | Logging previously defined in `Config.groovy` is now defined using Logback
`grails-app/conf/application.yml` | Configuration can now also be defined using YAML
`grails-app/init/PACKAGE_PATH/Application.groovy` | The `Application` class used By Spring Boot to start the application
#### Files Not Present in Grails 3.x Some files that were previously created by Grails 2.x are no longer created. These have either been removed or an appropriate replacement added. The following table lists files no longer in use:
File | Description
--- | ---
`application.properties` | The application name and version is now defined in `build.gradle`
`grails-app/conf/DataSource.groovy` | Merged together into `application.yml`
`lib` | Dependency resolution should be used to resolve JAR files
`web-app/WEB-INF/applicationContext.xml` | Removed, beans can be defined in `grails-app/conf/spring/resources.groovy`
`src/templates/war/web.xml` | Grails 3.0 no longer requires web.xml. Customizations can be done via Spring
`web-app/WEB-INF/sitemesh.xml` | Removed, sitemesh filter no longer present.
`web-app/WEB-INF/tld` | Removed, can be restored in `src/main/webapp` or `src/main/resources/WEB-INF`
## 3.1 Upgrading from Grails 3.0 Generally to upgrade an application from Grails 3.0 you can simply modify the version of Grails in `gradle.properties`. There are however some differences to Grails 3.0.x that are documented below. #### GORM 5 Upgrade Grails 3.1 ships with GORM 5, which is a near complete rewrite of GORM ontop of Groovy traits and is not binary compatible with the previous version of GORM. If you receive an error such as:
    Caused by: java.lang.ClassNotFoundException: org.grails.datastore.gorm.GormEntity$Trait$FieldHelper
        … 8 more
You are using a plugin or class that was compiled with a previous version of GORM and these will need to be recompiled to be Grails 3.1 and GORM 5 compatible. #### Hibernate Plugin For the GORM 5 release the `hibernate` plugin has been renamed to `hibernate4` (and there are `hibernate3` and `hibernate5` versions too). You should change your `build.gradle` to reflect that:
    compile 'org.grails.plugins:hibernate4'
#### Static Resources Path The default path for static resources resolved from `src/main/resources/public` has been changed to be nested under the `static/*` pattern instead of directly under the root of the application. For example a link in GSP pages such as:
    ${g.resource(dir:'files', file:'mydoc.pdf')}
Will produce a URI such as `/static/files/mydoc.pdf` instead of `/files/mydoc.pdf`. If you wish to revert to the previous behavior you can configure this in `application.yml`:
    grails:
        resources:
            pattern: '/**'
#### Filters Plugin Removed The Filters plugin was replaced by Interceptors in Grails 3.0.x, although the plugin was still present. In Grails 3.1.x the Filters plugin has been removed. If you still wish to use the filters plugin you can add a dependency on the previous version provided by Grails 3.0.x. For example:
    compile 'org.grails:grails-plugin-filters:3.0.12'
#### Spring Transactional Proxies Because the `grails.transactional.Transactional` transform already provides the ability to create transactional services without the need for proxies, traditional support for transactional proxies has been disabled by default. This means that if you have any services that use the `transactional` property and not the `Transactional` annotation they will need to be altered. For example the following service:
    class FooService {
        static transactional = true
    }
Becomes:

    import grails.transaction.Transactional@Transactional
    class FooService {}
In addition because in previous versions of a Grails `transactional` defaulted to `true` any services that do not declare `transactional` should be altered too. If you wish to revert to the previous behavior then transctional proxies can be re-enabled with the following configuration:
    grails:
        spring:
            transactionManagement:
                proxies: true
#### JSON Converter changes The default JSON converter no longer includes the `class` property by default. This can be re-enable with the following configuration:
    grails:
        converters:
            domain:
                include:
                    class: true
In addition the default JSON converter will no longer render the `id` property if it is `null`. #### JSON Builder Groovy Alignment The class `grails.web.JSONBuilder` has been deprecated and replaced with groovy.json.StreamingJsonBuilder, the default JSON builder within Groovy. This avoids confusion with the differences between JSON builders and better aligns with Groovy's core libraries. This also means that any `render` blocks that rendered JSON will need to be updated to use the groovy.json.StreamingJsonBuilder syntax. For example the following code:
    render(contentType:"application/json") {
        title = "The Stand"
    }
Should instead be written as:
    render(contentType:"application/json") {
        title "The Stand"
    }
If you are upgrading and prefer to continue to use the previous implementation then you can re-enable the deprecated JSONBuilder with the following configuration:
    grails:
        json:
            legacy:
                builder: true
#### JSON Views Replace JSON Converters With the addition of JSON views the previous API for using JSON converters is largely discouraged in favour of views. The converters plugin will in the future be separated into an external plugin and JSON views phased in to replace it. The JSON converter API is not deprecated, however JSON views provide a more fully featured, elegant API that is superior to writing JSON converters and/or marshallers. #### Spring Boot 1.3 and Spring 4.2 Grails 3.1 ships with upgraded third party libraries that may require changes. See the Spring Boot upgrade notes for information. Unlike Spring Boot 1.2, Spring Boot 1.3 no longer uses the Gradle Application Plugin so if you relied on any behavior the application plugin then the plugin will need to be re-applied to your `build.gradle`. Spring Boot 1.3 also uses Spring Security 4.x by default, so if you project depends on Spring Security 3.x you have to force a downgrade. For example:
    compile 'org.springframework.security:spring-security-core:3.2.9.RELEASE'
    compile 'org.springframework.security:spring-security-web:3.2.9.RELEASE'
#### Gradle `run` task no longer available by default Because the Gradle `run` task for application startup was provided by the Gradle Application Plugin (see above), it is no longer available by default. If you use Gradle to start up your application, use the `bootRun` task instead, or re-apply the Application plugin in your `build.gradle`. Note: If you don't have need of the Gradle Application plugin's features, but have custom Gradle tasks or IDE configurations that depend on `run`, you can supply your own `run` task that depends on `bootRun` in your `build.gradle`:
    task run(dependsOn: ['bootRun'])
#### Resource annotation defaults to JSON instead of XML The Resource annotation applied to domain classes defaults to XML in Grails 3.0.x, but in Grails 3.1.x and above it defaults to JSON. If you use this annotation with the expecation of produces XML responses as the default you can modify the definition as follows:

    import grails.rest.*@Resource(formats=['xml', 'json'])
    class MyDomainClass {}
This will restore the Grails 3.0.x behavior. #### Geb and HTMLUnit 2.18 If you use Geb with HTMLUnit (something that is not recommended, as a more native driver such as PhantomJS is recommended) you will need to upgrade your dependencies in `build.grade`:
    testRuntime 'org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1'
        testRuntime 'net.sourceforge.htmlunit:htmlunit:2.18'
Note that there are also some changes in behavior in HTMLUnit 2.18 that may cause issues in existing tests including: Expressions that evaluate the title (Example `$('title')`) now return blank and should be replaced with just `title` If you return plain text in a response without surrounding HTML tags, these are no longer regarded as valid responses and should be wrapped in the required tags. ## 3.2 Upgrading from Grails 2.x This guide takes you through the fundamentals of upgrading a Grails 2.x application or plugins to Grails 3.x. ## 3.2.1 Upgrading Plugins To upgrade a Grails 2.x plugin to Grails 3.x you need to make a number of different changes. This documentation will outline the steps that were taken to upgrade the Quartz plugin to Grails 3, each individual plugin may differ. #### Step 1 - Create a new Grails 3 plugin The first step is to create a new Grails 3 plugin using the command line:
    $ grails create-plugin quartz
This will create a Grails 3 plugin in the `quartz` directory. #### Step 2 - Copy sources from the original Grails 2 plugin The next step is to copy the sources from the original Grails 2 plugin to the Grails 3 plugin:

    # first the sources
    cp -rf ../quartz-2.x/src/groovy/ src/main/groovy
    cp -rf ../quartz-2.x/src/java/ src/main/groovy
    cp -rf ../quartz-2.x/grails-app/ grails-app
    cp -rf ../quartz-2.x/QuartzGrailsPlugin.groovy src/main/groovy/grails/plugins/quartz# then the tests
    cp -rf ../quartz-2.x/test/unit/* src/test/groovy
    mkdir -p src/integration-test/groovy
    cp -rf ../quartz-2.x/test/integration/* src/integration-test/groovy# then templates / other resources
    cp -rf ../quartz-2.x/src/templates/ src/main/templates
#### Step 3 - Alter the plugin descriptor You will need to add a package declaration to the plugin descriptor. In this case `QuartzGrailsPlugin` is modified as follows:
    // add package declaration
    package grails.plugins.quartz
    …
    class QuartzGrailsPlugin {
     …
    }
In addition you should remove the `version` property from the descriptor as this is now defined in `build.gradle`. #### Step 4 - Update the Gradle build with required dependencies The repositories and dependencies defined in `grails-app/conf/BuildConfig.groovy` of the original Grails 2.x plugin will need to be defined in `build.gradle` of the new Grails 3.x plugin:
    compile("org.quartz-scheduler:quartz:2.2.1") {
        exclude group: 'slf4j-api', module: 'c3p0'
      }
#### Step 5 - Modify Package Imports In Grails 3.x all internal APIs can be found in the `org.grails` package and public facing APIs in the `grails` package. The `org.codehaus.groovy.grails` package no longer exists. All package declaration in sources should be modified for the new location of the respective classes. Example `org.codehaus.groovy.grails.commons.GrailsApplication` is now `grails.core.GrailsApplication`. #### Step 5 - Migrate Plugin Specific Config to application.yml Some plugins define a default configuration file. For example the Quartz plugin defines a file called `grails-app/conf/DefaultQuartzConfig.groovy`. In Grails 3.x this default configuration can be migrated to `grails-app/conf/application.yml` and it will automatically be loaded by Grails without requiring manual configuration merging. #### Step 6 - Update plugin exclusions Old plugins may have a `pluginExcludes` property defined that lists the patterns for any files that should not be included in the plugin package. This is normally used to exclude artifacts such as domain classes that are used in the plugin's integration tests. You generally don't want these polluting the target application. This property is no longer sufficient in Grails 3, and nor can you use source paths. Instead, you must specify patterns that match the paths of the compiled classes. For example, imagine you have some test domain classes in the `grails-app/domain/plugin/tests` directory. You should first change the `pluginExcludes` value to
    def pluginExcludes = ["plugin/test/**"]
and then add this block to the build file:
    jar {
        exclude "plugin/test/**"
    }
The easiest way to ensure these patterns work effectively is to put all your non-packaged class into a distinct Java package so that there is a clean separation between the main plugin classes and the rest. #### Step 7 - Register ArtefactHandler Definitions In Grails 3.x ArtefactHandler definitions written in Java need to be declared in a file called `src/main/resources/META-INF/grails.factories` since these need to be known at compile time. If the `ArtefactHandler` is written in Groovy this step can be skipped as Grails will automatically create the `grails.factories` file during compilation. The Quartz plugin requires the following definition to register the `ArtrefactHandler`:
    grails.core.ArtefactHandler=grails.plugins.quartz.JobArtefactHandler
#### Step 8 - Migrate Code Generation Scripts Many plugins previously defined command line scripts in Gant. In Grails 3.x command line scripts have been replaced by two new features: Code generation scripts and Gradle tasks. If your script is doing simple code generation then for many cases a code generation script can replace an old Gant script. The `create-job` script provided by the Quartz plugin in Grails 2.x was defined in `scripts/CreateJob.groovy` as:

    includeTargets << grailsScript("_GrailsCreateArtifacts")target(createJob: "Creates a new Quartz scheduled job") {
        depends(checkVersion, parseArguments)    def type = "Job"
        promptForName(type: type)    for (name in argsMap.params) {
            name = purgeRedundantArtifactSuffix(name, type)
            createArtifact(name: name, suffix: type, type: type, path: "grails-app/jobs")
            createUnitTest(name: name, suffix: type)
        }
    }setDefaultTarget 'createJob'
A replacement Grails 3.x compatible script can be created using the `create-script` command:
    $ grails create-script create-job
Which creates a new script called `src/main/scripts/create-job.groovy`. Using the new code generation API it is simple to implement:

    description("Creates a new Quartz scheduled job") {
        usage "grails create-job [JOB NAME]"
        argument name:'Job Name', description:"The name of the job"
    }model = model( args[0] )
    render  template:"Job.groovy",
            destination: file( "grails-app/jobs/$model.packagePath/${model.simpleName}Job.groovy"),
            model: model
Please refer to the documentation on Creating Custom Scripts for more information. #### Migrating More Complex Scripts Using Gradle Tasks Using the old Grails 2.x build system it was relatively common to spin up Grails inside the command line. In Grails 3.x it is not possible to load a Grails application within a code generation script created by the create-script command. Instead a new mechanism specific to plugins exists via the create-command command. The `create-command` command will create a new ApplicationCommand, for example the following command will execute a query:

    import grails.dev.commands.*
    import javax.sql.*
    import groovy.sql.*
    import org.springframework.beans.factory.annotation.*class RunQueryCommand implements ApplicationCommand {  @Autowired
      DataSource dataSource  boolean handle(ExecutionContext ctx) {
          def sql = new Sql(dataSource)
          println sql.executeQuery("select * from foo")
          return true
      }
    }
With this command in place once the plugin is installed into your local Maven cache you can add the plugin to both the build classpath and the runtime classpath of the application's `build.gradle` file:
    buildscript {
      …
      dependencies {
        classpath "org.grails.plugins:myplugin:0.1-SNAPSHOT"
      }
    }
    …
    dependencies {
      runtime "org.grails.plugins:myplugin:0.1-SNAPSHOT"
    }
Grails will automatically create a Gradle task called `runQuery` and a command named `run-query` so both the following examples will execute the command:
    $ grails run-query
    $ gradle runQuery
#### Step 8 - Delete Files that were migrated or no longer used You should now delete and cleanup the project of any files no longer required by Grails 3.x (`BuildConfig.groovy`, `Config.groovy`, `DataSource.groovy` etc.) ## 3.2.2 Upgrading Applications Upgrading applications to Grails 3.x will require that you upgrade all plugins the application uses first, hence you should follow the steps in the previous section to first upgrade your plugins. #### Step 1 - Create a New Application Once the plugins are Grails 3.x compatible you can upgrade the application. To upgrade an application it is again best to create a new Grails 3 application using the "web" profile:
    $ grails create-app myapp
    $ cd myapp
#### Step 2 - Migrate Sources The next step is to copy the sources from the original Grails 2 application to the Grails 3 application:

    # first the sources
    cp -rf ../old_app/src/groovy/ src/main/groovy
    cp -rf ../old_app/src/java/ src/main/groovy
    cp -rf ../old_app/grails-app/ grails-app# then the tests
    cp -rf ../old_app/test/unit/ src/test/groovy
    mkdir -p src/integration-test/groovy
    cp -rf ../old_app/test/integration/ src/integration-test/groovy
#### Step 3 - Update the Gradle build with required dependencies The repositories and dependencies defined in `grails-app/conf/BuildConfig.groovy` of the original Grails 2.x application will need to be defined in `build.gradle` of the new Grails 3.x application. #### Step 4 - Modify Package Imports In Grails 3.x all internal APIs can be found in the `org.grails` package and public facing APIs in the `grails` package. The `org.codehaus.groovy.grails` package no longer exists. All package declaration in sources should be modified for the new location of the respective classes. Example `org.codehaus.groovy.grails.commons.GrailsApplication` is now `grails.core.GrailsApplication`. #### Step 5 - Migrate Configuration The configuration of the application will need to be migrated, this can normally be done by simply renaming `grails-app/conf/Config.groovy` to `grails-app/conf/application.groovy` and merging the content of `grails-app/conf/DataSource.groovy` into `grails-app/conf/application.groovy`. Note however that Log4j has been replaced by `grails-app/conf/logback.groovy` for logging, so any logging configuration in `grails-app/conf/Config.groovy` should be migrated to logback format. #### Step 6 - Migrate web.xml Modifications to Spring If you have a modified `web.xml` template then you will need to migrate this to Spring as Grails 3.x does not use a web.xml (although it is still possible to have on in `src/main/webapp/WEB-INF/web.xml`). New servlets and filters can be registered as Spring beans or with ServletRegistrationBean and FilterRegistrationBean respectively. #### Step 7 - Migrate Static Assets not handled by Asset Pipeline If you have static assets in your `web-app` directory of your Grails 2.x application such as HTML files, TLDs etc. these need to be moved. For public assets such as static HTML pages and so on these should go in `src/main/resources/public`. TLD descriptors and non public assets should go in `src/main/resources/WEB-INF`. As noted earlier, `src/main/webapp` folder can also be used for this purpose but it is not recommended. #### Step 8 - Migrate Tests Once the package names are corrected unit tests will continue to run, however any tests that extend the deprecated and removed JUnit 3 hierarchy will need to be migrated to Spock or JUnit 4. Integration tests will need to be annotated with the Integration annotation and should not extend GroovyTestCase or any JUnit 3 super class. | Quick Reference (hide)