3.2 Upgrading from Grails 2.x - Reference Documentation
Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari
Version: 3.1.9
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
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 caseQuartzGrailsPlugin is modified as follows:// add package declaration package grails.plugins.quartz … class QuartzGrailsPlugin { … }
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 ingrails-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 theorg.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 calledgrails-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 apluginExcludes 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 todef pluginExcludes = ["plugin/test/**"]jar {
exclude "plugin/test/**"
}Step 7 - Register ArtefactHandler Definitions
In Grails 3.x ArtefactHandler definitions written in Java need to be declared in a file calledsrc/main/resources/META-INF/grails.factories since these need to be known at compile time.If theThe Quartz plugin requires the following definition to register theArtefactHandleris written in Groovy this step can be skipped as Grails will automatically create thegrails.factoriesfile during compilation.
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.Thecreate-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'
create-script command:$ grails create-script create-job
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
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. Thecreate-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 } }
build.gradle file:buildscript {
…
dependencies {
classpath "org.grails.plugins:myplugin:0.1-SNAPSHOT"
}
}
…
dependencies {
runtime "org.grails.plugins:myplugin:0.1-SNAPSHOT"
}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 ingrails-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 theorg.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 renaminggrails-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 modifiedweb.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 yourweb-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.