Grails 4 Upgrade Notes
Tags: grails, groovy, micronaut, webdev
Published: 2019-05-17 03:17:12

Grails 4 is the next iteration of the Grails web framework. Grails is a developer friendly framework built on top of Spring-boot, Groovy, and now Micronaut.

# Status

Grails 4 is [released](https://objectcomputing.com/news/2019/07/11/grails-4-ga-released)! 
 
I've ported a non-trivial app from Grails 3.3.9 to 4.0.0 as well as updated to JDK11. The total effort was only a few hours - welcome news to many who are upgrading. 

Initial app startup time is about 15 seconds - 2x faster than the same app in Grails 3.3.9. 

Reloading has changed and there are a few options. The default option is from `spring-dev-tools` - fast restart. This restarts your app faster then a normal restart, but still can be extremely slow for large projects.

Hot reloading options are [JRebel](https://jrebel.com/software/jrebel/) - a paid option that works for JDK8/11 - or `spring-loaded` though it only supports JDK8 and is no longer maintained. [Instructions for spring-loaded](https://github.com/grails/grails-core/pull/11441)

IDE Support all works in Grails 4 (same as 3.3.9) - IntelliJ is still my recommended IDE for any Grails, Groovy, or Java developer.

# Updates

There are tons of updates to Grails 4 and the frameworks it builds upon. Here's a list of updates and release notes you should review if you're updating your apps.

* Grails 4 
  - [Upgrade notes](http://docs.grails.org/4.0.x/guide/upgrading.html)
  - [New app diff from 3.3.10 -> 4.0.0](https://github.com/erichelgeson/grails-versions/compare/3.3.10...4.0.0)
* [Micronaut 1.1](https://micronaut.io)
* [Spring Boot 2.1](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes)
* [Spring 5.1](https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-5.x)
* [Groovy 2.5](http://groovy-lang.org/releasenotes/groovy-2.5.html)
* [Hibernate 5.3/5.4 support](http://hibernate.org/orm/releases/5.4/)
* [Java 11](https://www.oracle.com/technetwork/java/javase/11all-relnotes-5013287.html)

# Install

[SDKMan](http://sdkman.io/) makes installing and managing a JVM and many frameworks a snap:
```bash
sdk install java 11.0.2-open
sdk install grails 4.0.3
```

# Plugins

Plugins are an essential part of the Grails developer experience. Luckily many plugins that worked in Grails 3 work out of the box in Grails 4 - or with only slight modifications due. 

## Working Plugins

* Spring-Security-Core `4.0.0`
  - New delegation password strategy:
    - https://www.baeldung.com/spring-security-5-password-storage
  - If you already used bcrypt can do it all at once too:
    - `UPDATE my_users SET password = CONCAT('{bcrypt}', password);`

* Spring-session-redis (boot starter)
  - Updated dependencies

```groovy
compile "org.springframework.boot:spring-boot-starter-data-redis"
compile "org.springframework.session:spring-session-data-redis"
```

* Spring-Websocket

```groovy
compile "org.grails.plugins:grails-spring-websocket:2.5.0.RC1"
```

* Grails-Quartz

```groovy
buildscript {
    dependencies {
        classpath 'org.grails.plugins:quartz:2.0.13' // Needed to compile *Job classes
    }
}

dependencies {
    compile 'org.grails.plugins:quartz:2.0.13'
    compile 'org.quartz-scheduler:quartz:2.2.1' // Is not pulled in by default
}
```

* Database Migration Plugin `3.1.0.RC1`

* Asset-Pipeline `3.1.0`

* External Config
  - Works - use RC1+
```groovy
    compile 'org.grails.plugins:external-config:2.0.0'
```

* Spring Security UI
  - https://github.com/grails-plugins/grails-spring-security-ui/issues/111


* Schwartz Plugin
  - `2.0.0.RC1`

* Grails Cache Plugin
  - `5.0.0.RC1`

* Spring Security OAuth2 Provider
  - `4.0.0-RC1`

* Sentry

* Grails Mail 
  - `3.0.0`

## Not working

* Audit-Logging Plugin
  - WIP @ https://github.com/robertoschwald/grails-audit-logging-plugin/pull/183

## Resolved

* ~~Asset Pipeline Handlebars issue:~~
  - Needed to update to change `//= require handlebars/handlebars.js` to `//= require handlebars-runtime`
```
2019-01-13 16:59:42.280  WARN --- [nio-8080-exec-1] asset.pipeline.DirectiveProcessor        : Unable to Locate Asset: /handlebars/handlebars.js
Warning: Nashorn engine is planned to be removed from a future JDK release
```
* ~~Gson Views~~
  - Resolved.
  - Unable to render json with simple objects (just get `null` response)
  - Domain classes dont render:
  ```
  Model variable [someDomain] of with value [Description] type [com.x.SomeDomain] is not of the correct type [com.x.SomeDomain]. Stacktrace follows:
  ```
   - Opened Issue https://github.com/grails/grails-views/issues/202

## Other notes Notes

* Hot reload for JDK8 only
  - `spring-loaded` supports only up to JDK8.
  - Fast reload takes about 5-6 seconds (hopefully can improve)

* `org.grails:grails-datastore-rest-client` no longer maintained
  - Use a different http client such as
      - `micronaut-http-client`, `http-builder-ng`, `feign`, `okhttp`, etc
  - Or use the old unmaintained GORM 6 version:
```groovy
compile('org.grails:grails-datastore-rest-client:6.1.9.RELEASE'){
    exclude group:'org.grails', module:'grails-plugin-converters'
}
```

* Groovy 2.5.x
  - Doesn't include the Date Utils helpers by default - need to add them in.
    - `compile 'org.codehaus.groovy:groovy-dateutil'`
    - (Should just update to `java.time.*`)
  - JDK 11 Warnings (expected)
    - https://dev.to/erichelgeson/removing-illegal-reflective-access-warnings-in-grails-4-393o
  - `.pop()` & collections behavior changed to align with Java - https://issues.apache.org/jira/browse/GROOVY-9388

* Dependencies changes (Gradle 5.1)
  - An issue where dependencies like `com.jameskleeh:excel-builder` - don't pull in their dependencies (eg: Apache POI)

* Hibernate Deprecated warnings (expected)
```
Hibernate's legacy org.hibernate.Criteria API is deprecated; use the JPA javax.persistence.criteria.CriteriaQuery instead
// and
HHH020100: The Ehcache second-level cache provider for Hibernate is deprecated.  See https://hibernate.atlassian.net/browse/HHH-12441 for details.
```
  - Hide them in `logback.groovy` 
    - `logger('org.hibernate.orm.deprecation', ERROR, ['STDOUT'], false)`

# Notes or tips of your own?

Join us over on the [grails-community](https://grails-slack.cfapps.io/) slack channel or comment below!