3 Upgrading from Grails 3.2.x 3.3.3

(Quick Reference) # 3 Upgrading from Grails 3.2.x Version: 3.3.3 # 3 Upgrading from Grails 3.2.x Grails 3.3 includes several changes to dependencies and Event publishing that may require changes to your application if you are upgrading from Grails 3.2.x.
| For information on upgrading from versions of Grails prior to Grails 3.2.x, see the Grails 3.2.x documentation on upgrading
### GORM 6.1 Upgrade GORM 6.1 includes changes that may require you to change your application. #### GORM Async Now Optional Notably `grails-datastore-gorm-async` is now optional and if you use the `task` method of GORM you will need to manually implement the `AsyncEntity` trait. #### Domain Autowiring Disabled Domain class autowiring is disabled by default due to its impact on performance. You can re-enable autowiring for all domains using the Default Mapping setting: grails-app/conf/application.groovy
    grails.gorm.default.mapping = {
            autowire true
    }
You can turn it on only for one domain class: grails-app/domain/demo/Book.groovy
    class Book {
        BookService bookService

        String name

        static mapping {
           autowire true
        }
        ...
        ..
        .
    }
#### Flush Mode now COMMIT by Default The default flush mode has been change to `COMMIT` due to the impact the previous flush mode `AUTO` has on read performance. You can switch back to `AUTO` use the `hibernate.flush.mode` setting in `application.yml` #### TransactionManager Chaining for Multiple Data Sources Disabled by Default In previous versions of Grails for multiple data sources a best effort transaction chain was used to attempt to manage a transaction across all configured data sources. As of Grails 3.3 this is disabled as it caused confusion since it isn’t a true XA implementation and also impacts performance as for every transaction you have a transaction for each data source bound regardless if that is the actual requirement. If your application depends on this feature you can re-enable it with the following configuration:
    grails:
      transaction:
        chainedTransactionManager:
          enabled: true
          blacklistPattern: '.*'
#### Tomcat JDBC GORM 6.1 and above now supports multiple connection pool options, so the `tomcat-jdbc` dependency is now optional. If you are upgrading you may need to add it (or another pool implementation) to your `build.gradle`: build.gradle
    runtime 'org.apache.tomcat:tomcat-jdbc'
### @TestMixin, @TestFor etc. Deprecated Since Grails 3.3, the Grails Testing Support Framework is used for all unit tests. The new testing framework is much simpler and provides a set of traits that improve readability, debugging and code completion. An example hello world test can be seen below:
    import spock.lang.Specification
    import grails.testing.web.controllers.ControllerUnitTest

    class HelloControllerTests extends Specification implements ControllerUnitTest<HelloController> {

        void "Test message action"() {
            when:"The message action is invoked"
            controller.message()

            then:"Hello is returned"
            response.text == 'Hello'
        }
    }
For more information on writing tests with Grails Testing Support see the dedicated documentation. To simplify upgrades you can can still use the previous AST transformation based framework by adding the following dependency to your Grails application: build.gradle
    testCompile "org.grails:grails-test-mixins:3.3.0"
### Default Logger Name In previous versions of Grails, if you did not specify a logger in the controller, service, etc, a `log` variable was injected for you. The naming convention of that logger was `grails.app.${artefactType}.package.class`. For example: `grails.app.controllers.foo.bar.MyController` To make the logger names more intuitive as well as to increase consistency between custom code, plugin dependencies, and third party libraries, the `grails.app.${artefactType}` convention was removed. The same class as above will now be referenced the same way as any standard class. The way the `log` variable gets injected was also changed to defer to the Slf4j transformation. That means it is no longer necessary to check `if (log.isDebugEnabled())`. The downside of this change is that it isn’t immediately simple to set up the same logging configuration for all controllers, for example. We think this can be solved with a package naming strategy that represents what your requirements are. ### Dependency Alterations In an effort to trim the size of the produced WAR file by Grails several dependencies are no longer resolved transtively including: `commons-lang` `gson` `aspectjweaver` `aspectjrt` `ehcache` If you are upgrading and have referenced any of these dependencies in your application you may need to alter your build to reference them. ### Spring Boot 1.5.x Spring Boot 1.5.x removes a number of deprecated classes, notably all of the classes within the `org.springframework.boot.context.embedded` package. If your application is referencing any of the classes within this package you will need to alter your imports to use `org.springframework.boot.web.servlet` instead. ### Reactor 2.x Deprecated and Removed Since Reactor 2.x is no longer being maintained and a new EventBus abstraction has been implemented, Reactor 2.x and all its dependencies have been removed. A compatibility layer has been provided to allow classes compiled with the previous version that uses Reactor to run, however all plugins and application code should be re-compiled and direct references to Reactor 2.x should be removed. ### Externalized Plugins Several plugins and libraries have been separated from Grails core into standalone projects. The following table summarizes the previous artefact id, the new artefact id and the location of the new sources:
Table 1. Externalized Plugins
Sources | Previous Artefact ID | New Artefact ID
--- | --- | ---
GSP | `org.grails:grails-plugin-gsp` | `org.grails.plugins:gsp`
Converters | `org.grails:grails-plugin-converters` | `org.grails.plugins:converters`
Async | `org.grails:grails-plugin-async` | `org.grails.plugins:async`
Events | `org.grails:grails-plugin-events` | `org.grails.plugins:events`
Testing Mixin | `org.grails:grails-plugin-testing` | `org.grails:grails-test-mixins`
### New Cache Plugin The Cache plugin has been re-written to no longer use Spring proxies but AST transformations instead. This improves startup and runtime performance, however one caveat is controller action response caching is no longer supported. ### Grails Domain Class API Deprecated The legacy classes that represent domain classes and their properties have been deprecated in favor of the mapping context API. The reason for this is to avoid duplicate parsing of the same class data between GORM and Grails and reduce overall startup time. The internal implementation of the methods in those classes now delegates to the mapping context. Due to that change, information about your domain classes is not available until the application context is available. In previous versions of Grails it was possible to access GrailsDomainClass instances and inspect the GrailsDomainClassProperty properties inside of the `doWithSpring` method in a plugin, for example. If you have code that follows that example, an error will be thrown that looks like "The method …​ cannot be accessed before GORM has initialized". The solution is to move any logic that executes before the context is available to somewhere else that executes after the context is available. All code that uses the GrailsDomainClass or GrailsDomainClassProperty classes should be re-written to use the mapping context api. To get started, inject the `grailsDomainClassMappingContext` bean. See the api documentation for more information on the MappingContext, PersistentEntity (GrailsDomainClass), and PersistentProperty (GrailsDomainClassProperty). The following table summarizes the deprecations:
Table 2. Deprecated Grails Domain Class API
Deprecated Class or Interface | Replacement
--- | ---
GrailsDomainClass | PersistentEntity
GrailsDomainClassProperty | PersistentProperty
The `GrailsDomainClassProperty` interface had many more methods to evaluate the type of the property such as `isOneToOne`, `isOneToMany` etc. and while `PersistentProperty` does not provide direct equivalents you can use `instanceof` as a replacement using one of the subclasses found in the org.grails.datastore.mapping.model.types package. The following table summarizes this:
Table 3. Deprecated GrailsDomainClassProperty method replacements
Deprecated Class or Interface | Replacement
--- | ---
`isAssociation()` | `property instanceof Association`
`isOneToOne()` | `property instanceof OneToOne`
`isManyToOne()` | `property instanceof ManyToOne`
`isEmbedded()` | `property instanceof Embedded`
`isManyToMany()` | `property instanceof ManyToMany`
`isBasicCollectionType()` | `property instanceof Basic`
### Grails Validator and ConstrainedProperty API Deprecated Grails' previous validation API (part of the `grails.validation` package) has been externalized into a separate project not part of the `grails-datastore-gorm-validation` dependency. This means that some interfaces previously part of Grails core are deprecated and the replacment in the external project should be used, including:
Table 4. Deprecated Grails Validator Classes
Deprecated Class or Interface | Replacement
--- | ---
GrailsDomainClassValidator | PersistentEntityValidator
CascadingValidator | CascadingValidator
ConstrainedProperty | ConstrainedProperty
Constraint | Constraint
AbstractConstraint | AbstractConstraint
Generally all classes within the `org.grails.validation` package are now deprecated. To register a custom constraint you should now use the ConstraintRegistry interface instead. The default ValidatorRegistry implements the `ConstraintRegistry` interface and can be autowired into any controller or service by declaring the following property:
    ValidatorRegistry gormValidatorRegistry
    ...
    gormValidatorRegistry.addConstraint(MyConstraint)
### Grails' Transactional AST Transforms Deprecated The transaction management AST transforms that shipped as part of Grails have been ported to GORM and improved to make it possible to use them outside of Grails. With this in mind Grails' versions of `@Transactional` and `@Rollback` found within the `grails.transaction` package have been deprecated in favour of GORMs versions. You should change your imports to use the GORM version instead of the Grails version. The following table summarizes the deprecated classes and their replacements:
Table 5. Deprecated Grails Transaction Transforms
Deprecated Class or Interface | Replacement
--- | ---
grails.transaction.Transactional | grails.gorm.transactions.Transactional
grails.transaction.Rollback | grails.gorm.transactions.Rollback
grails.transaction.NotTransactional | grails.gorm.transactions.NotTransactional
### Spring Proxies for Services No Longer Supported Earlier versions of Grails supported the use of Spring proxies for transaction management, but this support was disabled by default in Grails 3.2.x and developers encouraged to use the `@Transactional` AST transforms instead. In Grails 3.3 the support for Spring proxies has been dropped completely and you must use Grails' AST transforms. If you wish to continue to use Spring proxies for transaction management you will have to configure them manually use the appropriate Spring configuration. ### Datasource Plugin Refactor In previous versions of Grails and GORM the multiple data sources support relied on Grails' data sources plugin. The logic for configuring multiple data sources has moved to GORM and as a result of major changes to the dataSources plugin, beans for the lazy and unproxied representation of a dataSource are no longer available. The beans include: `dataSourceUnproxied` `dataSourceLazy` If you are referencing these beans you will need to remove these references and unwrap the single `dataSource` proxy manually. ### Task Groups Several tasks have had their groups changed to better reflect their purpose. If you’re having trouble finding a task, look through the different groups. ### Legacy JSON Builder Option Removed In a previous version of Grails, the JSON builder used by default for rendering JSON inline was changed. The previous behavior of using converters to build the JSON was able to be re-enabled by setting `grails.json.legacy.builder` to true. In Grails 3.3 that setting has been removed and it is no longer possible to use the legacy converter API to render JSON inline via the `render` method. | Quick Reference (hide)