3 Upgrading from Grails 3.3.x

Version: 4.0.0

3 Upgrading from Grails 3.3.x

Bump up Grails Version

You will need to upgrade your Grails version defined in gradle.properties.

Grails 3 app’s gradle.properties

gradle.properties

  1. ...
  2. grailsVersion=3.3.8
  3. ...

Grails 4 app’s gradle.properties

gradle.properties

  1. ...
  2. grailsVersion=4.0.0.BUILD-SNAPSHOT
  3. ...

Bump up GORM Version

If you were using GORM, you will need to update the version defined in gradle.properties.

Grails 3 app’s gradle.properties

gradle.properties

  1. ...
  2. gormVersion=6.1.10.RELEASE
  3. ...

Grails 4 app’s gradle.properties

gradle.properties

  1. ...
  2. gormVersion=7.0.0.RC1
  3. ...

Spring 5 and Spring Boot 2.1

Grails 4.0 is built on Spring 5 and Spring Boot 2.1. See the migration guide and release notes if you are using Spring specific features.

Hibernate 5.4 and GORM 7.x

Grails 4.x supports a minimum version of Hibernate 5.4 and GORM 7.x. Several changes have been made to GORM to support the newer version of Hibernate and simplify GORM itself.

The details of these changes are covered in the GORM upgrade documentation.

Spring Boot 2.1 Actuator

Please check the Spring Boot Actuator documentation since it has changed substantially from Spring Boot 1.5 the version Grails 3.x used.

If you had configuration such as:

grails-app/conf/application.yml - Grails 3.3.x

  1. endpoints:
  2. enabled: false
  3. jmx:
  4. enabled: true
  5. unique-names: true

replace it with:

grails-app/conf/application.yml - Grails 4.x

  1. spring:
  2. jmx:
  3. unique-names: true
  4. management:
  5. endpoints:
  6. enabled-by-default: false

Spring Boot Developer Tools and Spring Loaded

Previous versions of Grails used a reloading agent called Spring Loaded. Since this library is no longer maintained and does not support Java 11 support for Spring Loaded has been removed.

As a replacement, Grails 4 applications include Spring Boot Developer Tools dependencies in the build.gradle build script. If you are migrating a Grails 3.x app, please include the following set of dependencies:

build.gradle

  1. .
  2. ..
  3. ...
  4. configurations {
  5. developmentOnly
  6. runtimeClasspath {
  7. extendsFrom developmentOnly
  8. }
  9. }
  10. dependencies {
  11. developmentOnly("org.springframework.boot:spring-boot-devtools")
  12. ...
  13. ..
  14. }
  15. ...
  16. ..
  17. .

Also you should configure the necessary excludes for Spring Developer Tools in application.yml:

  1. spring:
  2. devtools:
  3. restart:
  4. exclude:
  5. - grails-app/views/**
  6. - grails-app/i18n/**
  7. - grails-app/conf/**

The above configuration prevents the server from restarting when views or message bundles are changed.

You can use Spring Developer Tools in combination with a browser extension such as the Chrome LiveReload extension to get automatic browserrefresh when you change anything in your Grails application.

Spring Boot Gradle Plugin Changes

Grails 4 is built on top of Spring Boot 2.1. Grails 3 apps were built on top of Spring Boot 1.x.

Your Grails 3 app’s build.gradle may have such configuration:

buid.gradle

  1. bootRun {
  2. addResources = true
  3. ...
  4. }

Grails 4 apps are built on top of Spring Boot 2.1. Starting from Spring Boot 2.0, the addResources property no longer exists. Instead, you need to set the sourceResources property to the source set that you want to use. Typically that’s sourceSets.main. This is described in the Spring Boot Gradle plugin’s documentation.

Your Grails 4 app’s build.gradle can be configured:

buid.gradle

  1. bootRun {
  2. sourceResources sourceSets.main
  3. ...
  4. }

Building executable jars for Grails Plugins

Spring Boot’s new Gradle Plugin:

The bootRepackage task has been replaced with bootJar and bootWar tasks for building executable jars and wars respectively. Both tasks extend their equivalent standard Gradle jar or war task, giving you access to all of the usual configuration options and behaviour.

If you had configuration such as:

buid.gradle | Grails 3

  1. // enable if you wish to package this plugin as a standalone application
  2. bootRepackage.enabled = false

replace it with:

buid.gradle | Grails 4

  1. // enable if you wish to package this plugin as a standalone application
  2. bootJar.enabled = false

Upgrading to Gradle 5

Grails 3 apps by default used Gradle 3.5. Grails 4 apps use Gradle 5.

To upgrade to Gradle 5 execute:

  1. ./gradlew wrapper --gradle-version 5.0

Due to changes in Gradle 5, transitive dependencies are no longer resolved for plugins. If your project makes use of a plugin that has transitive dependencies, you will need to add those explicitly to your build.gradle file.

If you customized your app’s build, other migrations may be necessary. Please checkGradle Upgrading your build documentation.

H2 Web Console

Spring Boot 2.1 includes native support for the H2 database web console. Since this is already included in Spring Boot the equivalent feature has been removed from Grails. The H2 console is therefore now available at /h2-console instead of the previous URI of /dbconsole. See Using H2’s Web Console in the Spring Boot documentation for more information.

Upgrade Hibernate

If you were using GORM for Hibernate implementation in your Grails 3 app, you will need to upgrade to Hibernate 5.4.

A Grails 3 build.gradle such as:

build.gradle

  1. dependencies {
  2. ...
  3. compile "org.grails.plugins:hibernate5"
  4. compile "org.hibernate:hibernate-core:5.1.5.Final"
  5. }

will be in Grails 4:

build.gradle

  1. dependencies {
  2. ...
  3. compile "org.grails.plugins:hibernate5"
  4. compile "org.hibernate:hibernate-core:5.4.0.Final"
  5. }

Migrating to Geb 2.3

Geb 1.1.x (a JDK 1.7 compatible version) was the version shipped by default with Grails 3. Grails 4 is no longer compatible with Java 1.7. You should migrate to Geb 2.3.

In Grails 3, if your build.gradle looks like:

build.gradle

  1. dependencies {
  2. testCompile "org.grails.plugins:geb:1.1.2"
  3. testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1"
  4. testRuntime "net.sourceforge.htmlunit:htmlunit:2.18"
  5. }

In Grails 4, you should replace it with:

build.gradle

  1. buildscript {
  2. repositories {
  3. ...
  4. }
  5. dependencies {
  6. ...
  7. classpath "gradle.plugin.com.energizedwork.webdriver-binaries:webdriver-binaries-gradle-plugin:$webdriverBinariesVersion" (1)
  8. }
  9. }
  10. ...
  11. ..
  12. repositories {
  13. ...
  14. }
  15. apply plugin:"idea"
  16. ...
  17. ...
  18. apply plugin:"com.energizedwork.webdriver-binaries" (1)
  19. dependencies {
  20. ...
  21. testCompile "org.grails.plugins:geb" (4)
  22. testRuntime "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion" (5)
  23. testRuntime "org.seleniumhq.selenium:selenium-firefox-driver:$seleniumVersion" (5)
  24. testRuntime "org.seleniumhq.selenium:selenium-safari-driver:$seleniumSafariDriverVersion" (5)
  25. testCompile "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion" (5)
  26. testCompile "org.seleniumhq.selenium:selenium-api:$seleniumVersion" (5)
  27. testCompile "org.seleniumhq.selenium:selenium-support:$seleniumVersion" (5)
  28. }
  29. webdriverBinaries {
  30. chromedriver "$chromeDriverVersion" (2)
  31. geckodriver "$geckodriverVersion" (3)
  32. }
  33. tasks.withType(Test) {
  34. systemProperty "geb.env", System.getProperty('geb.env')
  35. systemProperty "geb.build.reportsDir", reporting.file("geb/integrationTest")
  36. systemProperty "webdriver.chrome.driver", System.getProperty('webdriver.chrome.driver')
  37. systemProperty "webdriver.gecko.driver", System.getProperty('webdriver.gecko.driver')
  38. }

gradle.properties

  1. gebVersion=2.3
  2. seleniumVersion=3.12.0
  3. webdriverBinariesVersion=1.4
  4. hibernateCoreVersion=5.1.5.Final
  5. chromeDriverVersion=2.44 (2)
  6. geckodriverVersion=0.23.0 (3)
  7. seleniumSafariDriverVersion=3.14.0
1Includes Webdriver binaries Gradle plugin.
2Set the appropriate Webdriver for Chrome version.
3Set the appropriate Webdriver for Firefox version.
4Includes the Grails Geb Plugin dependency which has a transitive dependency to geb-spock. This is the dependency necessary to work with Geb and Spock.
5Selenium and different driver dependencies.

Create also a Geb Configuration file at src/integration-test/resources/GebConfig.groovy.

src/integration-test/resources/GebConfig.groovy

  1. import org.openqa.selenium.chrome.ChromeDriver
  2. import org.openqa.selenium.chrome.ChromeOptions
  3. import org.openqa.selenium.firefox.FirefoxDriver
  4. import org.openqa.selenium.firefox.FirefoxOptions
  5. import org.openqa.selenium.safari.SafariDriver
  6. environments {
  7. // You need to configure in Safari -> Develop -> Allowed Remote Automation
  8. safari {
  9. driver = { new SafariDriver() }
  10. }
  11. // run via “./gradlew -Dgeb.env=chrome iT”
  12. chrome {
  13. driver = { new ChromeDriver() }
  14. }
  15. // run via “./gradlew -Dgeb.env=chromeHeadless iT”
  16. chromeHeadless {
  17. driver = {
  18. ChromeOptions o = new ChromeOptions()
  19. o.addArguments('headless')
  20. new ChromeDriver(o)
  21. }
  22. }
  23. // run via “./gradlew -Dgeb.env=firefoxHeadless iT”
  24. firefoxHeadless {
  25. driver = {
  26. FirefoxOptions o = new FirefoxOptions()
  27. o.addArguments('-headless')
  28. new FirefoxDriver(o)
  29. }
  30. }
  31. // run via “./gradlew -Dgeb.env=firefox iT”
  32. firefox {
  33. driver = { new FirefoxDriver() }
  34. }
  35. }

Deprecated classes

The following classes, which were deprecated in Grails 3.x, have been removed in Grails 4. Please, check the list below to find a suitable replacement:

Removed Class Alternative
org.grails.datastore.gorm.validation.constraints.UniqueConstraint org.grails.datastore.gorm.validation.constraints.builtin.UniqueConstraint
grails.util.BuildScope
grails.transaction.GrailsTransactionTemplate grails.gorm.transactions.GrailsTransactionTemplate
org.grails.transaction.transform.RollbackTransform org.grails.datastore.gorm.transactions.transform.RollbackTransform
grails.transaction.NotTransactional grails.gorm.transactions.NotTransactional
grails.transaction.Rollback grails.gorm.transactions.Rollback
grails.transaction.Transactional grails.gorm.transactions.Transactional
org.grails.config.FlatConfig
org.grails.core.metaclass.MetaClassEnhancer Use traits instead.
org.grails.core.util.ClassPropertyFetcher org.grails.datastore.mapping.reflect.ClassPropertyFetcher
org.grails.transaction.transform.TransactionalTransform org.grails.datastore.gorm.transactions.transform.TransactionalTransform
grails.core.ComponentCapableDomainClass
grails.core.GrailsDomainClassProperty Use the org.grails.datastore.mapping.model.MappingContext API instead
org.grails.core.DefaultGrailsDomainClassProperty
org.grails.core.MetaGrailsDomainClassProperty
org.grails.core.support.GrailsDomainConfigurationUtil Use the org.grails.datastore.mapping.model.MappingContext and org.grails.datastore.mapping.model.MappingFactory APIs instead
org.grails.plugins.domain.DomainClassPluginSupport
org.grails.plugins.domain.support.GormApiSupport
org.grails.plugins.domain.support.GrailsDomainClassCleaner Handled by org.grails.datastore.mapping.model.MappingContext now
grails.validation.AbstractConstraint Use org.grails.datastore.gorm.validation.constraints.AbstractConstraint instead
grails.validation.AbstractVetoingConstraint org.grails.datastore.gorm.validation.constraints.AbstractVetoingConstraint
grails.validation.CascadingValidator grails.gorm.validation.CascadingValidator
grails.validation.ConstrainedProperty grails.gorm.validation.ConstrainedProperty
grails.validation.Constraint grails.gorm.validation.Constraint
grails.validation.ConstraintFactory org.grails.datastore.gorm.validation.constraints.factory.ConstraintFactory
grails.validation.VetoingConstraint grails.gorm.validation.VetoingConstraint
grails.validation.ConstraintException
org.grails.validation.BlankConstraint org.grails.datastore.gorm.validation.constraints.BlankConstraint
org.grails.validation.ConstrainedPropertyBuilder org.grails.datastore.gorm.validation.constraints.builder.ConstrainedPropertyBuilder
org.grails.validation.ConstraintDelegate
org.grails.validation.ConstraintsEvaluatorFactoryBean org.grails.datastore.gorm.validation.constraints.eval.ConstraintsEvaluator
org.grails.validation.CreditCardConstraint org.grails.datastore.gorm.validation.constraints.CreditCardConstraint
org.grails.validation.DefaultConstraintEvaluator org.grails.datastore.gorm.validation.constraints.eval.DefaultConstraintEvaluator
org.grails.validation.DomainClassPropertyComparator
org.grails.validation.EmailConstraint org.grails.datastore.gorm.validation.constraints.EmailConstraint
org.grails.validation.GrailsDomainClassValidator grails.gorm.validation.PersistentEntityValidator
org.grails.validation.InListConstraint org.grails.datastore.gorm.validation.constraints.InListConstraint
org.grails.validation.MatchesConstraint org.grails.datastore.gorm.validation.constraints.MatchesConstraint
org.grails.validation.MaxConstraint org.grails.datastore.gorm.validation.constraints.MaxConstraint
org.grails.validation.MaxSizeConstraint org.grails.datastore.gorm.validation.constraints.MaxSizeConstraint
org.grails.validation.MinConstraint org.grails.datastore.gorm.validation.constraints.MinConstraint
org.grails.validation.MinSizeConstraint org.grails.datastore.gorm.validation.constraints.MinSizeConstraint
org.grails.validation.NotEqualConstraint org.grails.datastore.gorm.validation.constraints.NotEqualConstraint
org.grails.validation.NullableConstraint org.grails.datastore.gorm.validation.constraints.NullableConstraint
org.grails.validation.RangeConstraint org.grails.datastore.gorm.validation.constraints.RangeConstraint
org.grails.validation.ScaleConstraint org.grails.datastore.gorm.validation.constraints.ScaleConstraint
org.grails.validation.SizeConstraint org.grails.datastore.gorm.validation.constraints.SizeConstraint
org.grails.validation.UrlConstraint org.grails.datastore.gorm.validation.constraints.UrlConstraint
org.grails.validation.ValidatorConstraint org.grails.datastore.gorm.validation.constraints.ValidatorConstraint
org.grails.validation.routines.DomainValidator Replaced by newer version of commons-validation
org.grails.validation.routines.InetAddressValidator Replaced by newer version of commons-validation
org.grails.validation.routines.RegexValidator Replaced by newer version of commons-validation
org.grails.validation.routines.ResultPair Replaced by newer version of commons-validation
org.grails.validation.routines.UrlValidator Replaced by newer version of commons-validation
grails.web.JSONBuilder groovy.json.StreamingJsonBuilder

Grails-Java8

For those who have added a dependency on the grails-java8 plugin, all you should need to do is simply remove the dependency. All of the classes in the plugin have been moved out to their respective projects.

Profiles Deprecation

A few of the profiles supported in Grails 3.x will no longer be maintained going forward and as a result it is no longer possible to create applications when them in the shorthand form. When upgrading existing projects, it will be necessary to supply the version for these profiles.

  • org.grails.profiles:angularjsorg.grails.profiles:angularjs:1.1.2

  • org.grails.profiles:webpackorg.grails.profiles:webpack:1.1.6

  • org.grails.profiles:react-webpackorg.grails.profiles:react-webpack:1.0.8

Scheduled Methods

In Grails 3 no configuration or additional changes were necessary to use the Spring @Scheduled annotation. In Grails 4 you must apply the @EnableScheduling annotation to your application class in order for scheduling to work.