We have a long history of maintaining a fairly large grails application which we took from Grails 1.0 to 4.0. We sometimes decided to skip some intermediate releases of the framework because of problems or missing incentives to upgrade. If your are interested in our experiences of the past, feel free to have a look our stories:
- 2016-04: Grails 2.3 to 2.4/2.5 (failed)
- 2014-06: Grails 2.2 to 2.3
- 2013-10: Grails 1.3 to 2.2
- 2011-03: Grails 1.0 to 1.3
This is the next installment of our journey to the latest and greatest version of the Grails framework. This time the changes do not seem as intimidating like going from 2.x to 3.x. There are less moving parts, at least from the perspective of an application developer where almost everything stayed the same (gradle build system, YAML configuration, Geb functional tests etc.). Under the hood there are of course some bigger changes like new major versions of GORM/Hibernate and Spring Boot and the switch to Micronaut as the parent application context.
The hurdles we faced
- For historical reasons our application uses flush mode “auto”. This does not work until today, see https://github.com/grails/grails-core/issues/11376
- The most work intensive change is that Hibernate 5 requires you to perform your work in transactions. So we have dozens of places where we need to add missing
@Transactionalannotations to make especially saving domain objects work. Therefore we have to essentially test the whole application.
- The handling of HibernateProxies again became more intransparent which led to numerous
IllegalArgumentExceptions (“object ist not an instance of declaring type”). Sometimes we could move from generated
hashCode()/equals()implementations to the groovy-Annotation
@EqualsAndHashCode(actually a good thing) whereas in other places we did manual unwrapping or switched to eager fetching to avoid these problems.
In addition we faced minor gotchas like changed configuration entries. The one that cost us some hours was the subtle change of
server.servlet.context-path but nothing major or blocking.
We also had to transform many of our unit and integration tests to Spock and the new Grails Testing Support framework. It makes the tests more readable anyway and feels more fruitful than trying to debug the old-style Grails Test Mixins based tests.
One major improvement for us in the Grails ecosystem is the good news that the shiro plugin is again officially available, maintained and cleaned up (see https://github.com/nerdErg/grails-shiro). Now we do not need to use our own poor man’s port anymore.
Regarding the proclaimed performance improvements and reduced memory consumptions we do not have final numbers or impressions yet. We will deliver results on this front in the future.
More important is an incovenience we are still facing regarding hot-code-reloading. It does not work for us even using OpenJDK 8 with the old spring-loaded mechanism. The new restart-style of micronaut/spring-boot is not really productive for us because the startup times can easily reach the minute range even on fast hardware.
My hottest advice for you is this one:
Create a fresh Grails 4 app and compare central files like
build.gradleto get up to the state-of-the-art.
While this upgrade still was a lot of work and meant many places had to be touched it was a lot smoother than many of the previous ones. We hope that things improve further in the future as the technological stack is up-to-date and much more mature than in the early days…