////
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
////

### Upgrade Instructions for Grails and Related Dependencies

To ensure compatibility with Grails 6, you must update the following versions in your project:

#### 1. Java 11 as Baseline:

Starting from Grails 6, Java 11 serves as the baseline requirement for the framework. When upgrading to Grails 6, ensure that your project is configured to use Java 11. This compatibility with Java 11 allows you to take advantage of the latest features, security enhancements, and performance improvements provided by Java 11.

Please make sure to update your project's Java version to 11 before proceeding with the Grails 6 upgrade. Doing so will ensure a seamless transition to the latest version of Grails and enable you to enjoy all the benefits that Java 11 has to offer.

#### 2. The New Grails CLI:

Grails 6 comes with a completely revamped and highly efficient Command Line Interface (CLI) that enables you to generate applications and plugins at a remarkable speed. For instance, you can now use the new CLI to create a new Grails 6 application with the following command:

```bash
grails create-app my-app
```

The new CLI also allows you to generate plugins easily. For example, to create a new plugin named "my-plugin," you can use the following command:

```bash
grails create-plugin my-plugin
```

One notable improvement in Grails 6 is that it no longer supports certain commands that performed redundant tasks, such as the outdated `grails run-app` command. Instead, it recommends using the Gradle `bootRun` task for running your application, which offers better performance and functionality.

For example, to run your Grails 6 application, you can use the following command:

```bash
./gradlew bootRun
```

As a result of these improvements, the new CLI provides a more streamlined and efficient way to work with Grails applications and plugins.

Overall, Grails 6 offers a significantly improved development experience with its new CLI, optimized commands, and advanced features for generating applications and plugins.

#### 3. Setting Grails Version and Grails Gradle Plugin:

To upgrade to Grails 6, it's important to configure the appropriate versions in the `gradle.properties` file as shown below:

.gradle.properties
```properties
grailsVersion=6.0.0
grailsGradlePluginVersion=6.0.0

```

By specifying the above versions, you'll gain access to the latest features, improvements, and bug fixes introduced in Grails 6. Upgrading to this version empowers your application with enhanced performance and improved security. Additionally, it allows you to leverage the latest advancements in the Grails framework for a more efficient and secure development experience.

#### 4. GORM Version:

If your project utilizes GORM, ensure to update the version in the `gradle.properties` file as demonstrated below:

.gradle.properties
```properties
gormVersion=8.0.0
```

By upgrading to GORM 8.0.0, you will benefit from essential updates and optimizations. This upgrade guarantees seamless interactions with your database and enhances your data management experience. Staying current with GORM allows you to take advantage of the latest database features and improvements, thereby optimizing the performance and functionality of your application.

#### 5. Gradle Version:

Grails 6 uses Gradle 7.6.2 which offers performance improvements, bug fixes, and new features over previous versions. Upgrading to the latest Gradle version helps accelerate your build processes and ensures compatibility with other dependencies.

##### 5.1. Upgrade to Gradle 7.6.2

Run the following command to update the Gradle wrapper to the desired version (e.g., Gradle 7.6.2):

```bash
./gradlew wrapper --gradle-version 7.6.2
```

This command will download the specified Gradle version and update the Gradle wrapper settings in your project.

##### 5.2. Check Gradle Version:

After the command finishes, you can verify that the Gradle version has been updated by checking the `gradle-wrapper.properties` file located in the `gradle/wrapper` directory. The `distributionUrl` in the file should now point to the Gradle 7.6.2 distribution:

```
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip
```


##### 5.3. Build the Project:

After updating the Gradle wrapper, you can now build your Grails project using the updated Gradle version:

```bash
./gradlew build
```

This will initiate the build process with the new Gradle version.

#### 6. Embracing Modern Plugin Management with Grails 6

In Gradle, there are two main ways to add plugins to your project: the `plugins` block and the `apply plugin` statement.

Grails 6 introduces a significant change in how plugins are managed by adopting the Gradle `plugins` block instead of the traditional `apply plugin` statements. This shift streamlines the project's build configuration and brings it more in line with modern Gradle conventions. New Grails projects will now utilize the `plugins` block to manage plugin dependencies and configurations.

**Using the `plugins` Block in Grails 6:**

With the new approach, adding plugins to a Grails 6 project is more explicit and organized. In your `build.gradle` file, you can declare plugins within the `plugins` block, specifying the plugin's ID and version.

Here's an example of adding the `views-json` plugin using the `plugins` block:

.build.gradle
```groovy
plugins {
    id 'org.grails.plugins.views-json' version '3.0.0'
}
```


**Managing Multiple Plugins:**

The `plugins` block allows you to add multiple plugins, each on its own line. This enhances clarity and makes it easier to manage plugin dependencies.

.build.gradle
```groovy
plugins {
    id 'org.grails.plugins.views-json' version '3.0.0'
    // Add other plugins as needed
}
```

**Moving Older Applications to the New Approach:**

If you are migrating an older Grails application to Grails 6, you can update the plugin declarations from `apply plugin` to the `plugins` block. For example, if your previous application used the `views-json` plugin, you can modify the build.gradle as follows:

**Before (Using `apply plugin`):**

.build.gradle
```groovy
apply plugin: 'org.grails.plugins.views-json'
```


**After (Using `plugins` Block in Grails 6):**

.build.gradle
```groovy
plugins {
    id 'org.grails.plugins.views-json' version '3.0.0'
}
```

By migrating to the `plugins` block, your Grails 6 project will adhere to modern Gradle conventions, making it easier to manage plugin dependencies and configurations. This new approach maintains consistency and enhances the overall structure of the project, ensuring a smoother and more efficient development process.

#### 7. GORM for MongoDB Sync Driver:

The GORM for MongoDB is updated to support the latest mongodb-driver-sync. If you are using GORM for MongoDB and making use of specific MongoDB Driver or low-level Mongo API features, consider checking the https://mongodb.github.io/mongo-java-driver/4.0/upgrading/[Upgrading to the 4.0 Driver guide].

This update ensures seamless integration with MongoDB, access to new features, and improved performance while interacting with your MongoDB database.

#### 8. Asset Pipeline Plugin:

In Grails 6, there is an update to the Asset Pipeline Plugin, which is now version 4.3.0. The Asset Pipeline Plugin is a crucial component in Grails applications, responsible for managing frontend assets like stylesheets, JavaScript files, and images. The update to version 4.3.0 brings several improvements and new features to enhance the management and processing of frontend assets in your Grails projects.

The asset-pipeline plugin 4.3.0 offers new features for managing and processing your frontend assets, ensuring they are efficiently bundled and served to your users.

#### 9. Spring 5.3:

Grails 6 is built on Spring 5.3.27. If your project uses Spring-specific features, refer to the https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-5.x#upgrading-to-version-53[Upgrading to Spring 5.3 guide].

Spring 5.3 introduces enhancements and fixes to the Spring framework, providing you with the latest improvements in dependency injection, web frameworks, and other Spring-related functionalities.

#### 10. Spring Boot 2.7:

Grails 6 updates to Spring Boot 2.7. For more information, consult the https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.7-Release-Notes[Spring Boot 2.7 Release Notes]

Spring Boot 2.7 comes with new features, performance enhancements, and compatibility improvements, making it a solid foundation for your Grails application.

#### 11. Micronaut 3.9.3:

Grails 6 is shipped with Micronaut 3.9.3. If you are using specific Micronaut features, refer to the https://micronaut-projects.github.io/micronaut-docs-mn3/3.9.3/guide/#upgrading[Upgrading to Micronaut 3.x guide].

Micronaut 3.9.3 brings new capabilities, improvements, and bug fixes, empowering your application with a powerful and lightweight microservices framework.

#### 12. Micronaut for Spring 4.5.1:

Grails 6 is updated to use Micronaut for Spring 4.5.1. For more information, check out the https://github.com/micronaut-projects/micronaut-spring/releases/tag/v4.5.1[release notes].

Micronaut for Spring 4.5.1 provides seamless integration between Micronaut and Spring, allowing you to leverage the strengths of both frameworks in your Grails project.

===== 12.27 stop-app no longer uses JMX or the Actuator shutdown endpoint

The interactive CLI `stop-app` command no longer stops a running application through JMX or the Spring Boot Actuator `/actuator/shutdown` endpoint. Both mechanisms were unreliable on current JDKs and default configurations.

Instead, `run-app` records the application's process id in a PID file (`build/run-app.pid`) and `stop-app` reads that file to stop the process directly. As a result:

* The `--host` and `--port` options of `stop-app` have been removed. `stop-app` now stops the application started by `run-app` for the current project. If you previously scripted `grails stop-app --host=... --port=...`, drop those options.
* `stop-app` only stops an application that was started with `run-app` for the same project. It can be invoked from interactive mode or from a separate terminal.
* On Linux and macOS the application is shut down gracefully (the equivalent of `SIGTERM`), so JVM shutdown hooks and Spring's orderly shutdown run. On Windows the application is terminated on a best-effort basis and a graceful shutdown is not guaranteed.
* Every `bootRun` invocation (including a direct `./gradlew bootRun`) now writes `build/run-app.pid` while the application is running; the file is removed once the application stops. Customizing the Gradle build directory (`layout.buildDirectory`) is not supported by `stop-app`, which always looks for the PID file under the conventional `build` directory.

==== 13. Upgrading the Spring Security Plugins

As of Grails 7, the Spring Security plugins -- Core, ACL, CAS, LDAP, OAuth2, REST, and UI -- are part of Grails core and are documented in the xref:security.adoc#springSecurity[Security > Spring Security] section of this guide. This section covers upgrading an application from the Grails 6.x era (plugin versions 5.x/6.x, Spring Security 5.8.x) to Grails 7 (Spring Security 6.x).

NOTE: Documentation for earlier, independently-versioned plugin releases remains available at the https://apache.github.io/grails-spring-security/[legacy Spring Security plugin documentation site].

===== Dependency Changes

All Spring Security plugin artifacts have moved to the `org.apache.grails` group. The most notable change is that `spring-security-core` has been renamed to `grails-spring-security` (dropping the `-core` suffix).

Update your `build.gradle` dependencies as follows:

[cols="1,1",options="header"]
|===
| Old Dependency | New Dependency

| `org.grails.plugins:spring-security-core`
| `org.apache.grails:grails-spring-security`

| `org.grails.plugins:spring-security-acl`
| `org.apache.grails:grails-spring-security-acl`

| `org.grails.plugins:spring-security-cas`
| `org.apache.grails:grails-spring-security-cas`

| `org.grails.plugins:spring-security-ldap`
| `org.apache.grails:grails-spring-security-ldap`

| `org.grails.plugins:spring-security-oauth2`
| `org.apache.grails:grails-spring-security-oauth2`

| `org.grails.plugins:spring-security-rest`
| `org.apache.grails:grails-spring-security-rest`

| `org.grails.plugins:spring-security-rest-gorm`
| `org.apache.grails:grails-spring-security-rest-datamapping`

| `org.grails.plugins:spring-security-rest-grailscache`
| `org.apache.grails:grails-spring-security-rest-grails-cache`

| `org.grails.plugins:spring-security-rest-memcached`
| `org.apache.grails:grails-spring-security-rest-memcached`

| `org.grails.plugins:spring-security-rest-redis`
| `org.apache.grails:grails-spring-security-rest-redis`

| `org.grails.plugins:spring-security-ui`
| `org.apache.grails:grails-spring-security-ui`
|===

The coordinate rename script described in the *Coordinate Changes* section above also updates these Spring Security artifacts automatically.

====== Example

A typical Spring Security Core dependency change:

[source,groovy]
.build.gradle
----
// Before (Grails 6)
implementation 'org.grails.plugins:spring-security-core:6.1.1'

// After (Grails 7)
implementation 'org.apache.grails:grails-spring-security'
----

NOTE: With the unified Grails BOM, versions are managed automatically when using a Grails Gradle plugin. You no longer need to specify the version explicitly.

===== REST Plugin Token Storage Submodules

If you use the Spring Security REST plugin with a specific token storage backend, note the following renames:

* `spring-security-rest-gorm` is now `grails-spring-security-rest-datamapping` (reflecting the rename of GORM to Grails Data Mapping)
* `spring-security-rest-grailscache` is now `grails-spring-security-rest-grails-cache`
* `spring-security-rest-memcached` is now `grails-spring-security-rest-memcached`
* `spring-security-rest-redis` is now `grails-spring-security-rest-redis`

===== Spring Security 6.x Changes

The underlying Spring Security framework has been upgraded from 5.8.x to 6.x. Key changes that may affect your application:

* **Jakarta EE namespace**: Spring Security 6 uses `jakarta.servlet` instead of `javax.servlet`. See the https://docs.spring.io/spring-security/reference/migration/index.html[Spring Security Migration Guide] for details.
* **Security filter chain configuration**: The `WebSecurityConfigurerAdapter` has been removed in Spring Security 6. If you have custom security configurations extending this class, you will need to migrate to the component-based approach. The Grails Spring Security plugin handles the core filter chain configuration internally, but any custom Spring Security beans may need updating.
* **Default security behaviors**: Some default behaviors have changed in Spring Security 6 (e.g., CSRF protection, session management). Review the https://docs.spring.io/spring-security/reference/migration-7/index.html[Spring Security reference documentation] for the complete list of changes.

===== Configuration Compatibility

The `grails.plugin.springsecurity.*` configuration namespace remains unchanged. Your existing `application.groovy` or `application.yml` security configuration should work without modification after updating the dependencies.

If you encounter any issues during the upgrade, please file an issue at https://github.com/apache/grails-core/issues[the grails-core GitHub repository].

==== 14. Changes in CLI- and Forge-generated configuration files

From Grails 7.0.11 onwards, the CLIs (`grails-shell-cli` and `grails-forge-cli`) and the https://start.grails.org[Grails Forge website] no longer include several previously generated properties in `application.yml`.

Most of the removed entries simply restated framework defaults, so omitting them reduces clutter without changing behavior. However, `grails.urlmapping.cache.maxsize` is a special case: older generated applications explicitly set it to `1000`, while the framework default is now `5000`. If you want to preserve the older generated cache size, keep that property in your application.

If the application you are upgrading relies on a custom value for any of the following properties, or if you want to preserve the previous generated value of `grails.urlmapping.cache.maxsize`, keep that setting in your `application.yml` file.

These are the properties that were removed from generated `application.yml` files:

[source,yml]
.application.yml
----
grails:
  controllers:
    defaultScope: singleton # already framework default
  converters:
    encoding: UTF-8 # already framework default
  mime:
    disable:
      accept:
        header:
          userAgents: # already framework default
            - Gecko
            - WebKit
            - Presto
            - Trident
  urlmapping:
    cache:
      maxsize: 1000 # Attention! framework default: 5000
  views:
    default:
      codec: html # redundant because GSP expressions already default to html encoding
    gsp:
      codecs:
        expression: html # already framework default
        taglib: none # already framework default
        staticparts: none # already framework default
----

==== 15. grails-micronaut-bom Required when using Micronaut

Grails 7 introduces a dedicated `grails-micronaut-bom` for projects that integrate with Micronaut.
The Micronaut platform declares its own managed versions for libraries such as `javaparser-core` that conflict with the versions managed by `grails-bom`.
Without an enforced BOM, Gradle's default conflict resolution (highest version wins) allows the Micronaut platform to silently override `grails-bom` versions, leading to binary incompatibilities at runtime.

The `grails-micronaut-bom` layers Micronaut-specific overrides on top of `grails-bom`. When applied as `enforcedPlatform`, all of its constraints become strictly versioned and cannot be overridden by any transitive dependency.

Regular Grails projects (without Micronaut) should continue to use `platform("org.apache.grails:grails-bom:$grailsVersion")` and will receive the Spring-managed dependency versions. Applying `enforcedPlatform` to those projects is unnecessary and would force grails-bom versions over Spring's managed defaults.

The Grails Gradle Plugin will error at configuration time if `grails-micronaut` is detected and `grails-micronaut-bom` is not applied as `enforcedPlatform`.

[source,groovy]
.build.gradle
----
dependencies {
    // enforcedPlatform on grails-micronaut-bom is required when using grails-micronaut
    implementation enforcedPlatform("org.apache.grails:grails-micronaut-bom:$grailsVersion")

    implementation 'org.apache.grails:grails-micronaut'
}
----

The Micronaut auto-setup (which performs the validation along with other Micronaut-specific configuration) defaults to on. It can be disabled via the `grails` extension when a project deliberately deviates from the recommended setup:

[source,groovy]
.build.gradle
----
grails {
    micronautAutoSetup = false // not recommended
}
----

NOTE: Applications generated by the Grails Forge automatically use `enforcedPlatform` on `grails-micronaut-bom` when the Micronaut feature is selected.

==== 16. Upgrading the Quartz Plugin

As of Grails 7, the Quartz plugin is part of Grails core and is documented in the xref:backgroundJobs.adoc#backgroundJobsAdvanced[Background Jobs > Advanced Scheduling] section of this guide.

NOTE: Documentation for earlier, independently-versioned plugin releases remains available at the https://apache.github.io/grails-quartz/[legacy Quartz plugin documentation site].

===== 16.1 Coordinate Changes

The plugin artifact has moved to the `org.apache.grails` group and has been renamed from `quartz` to `grails-quartz`, matching the naming convention used by the other Grails plugins.

[cols="1,1"]
|===
| Grails 6 Coordinate | Grails 7 Coordinate

| `org.grails.plugins:quartz`
| `org.apache.grails:grails-quartz`
|===

The coordinate rename script described in the *Coordinate Changes* section above also updates this artifact automatically.

The version is now managed by the Grails BOM, so it should be removed from the dependency declaration:

[source,groovy]
.build.gradle
----
dependencies {
    // Grails 6
    // implementation 'org.grails.plugins:quartz:2.0.13'

    // Grails 7
    implementation 'org.apache.grails:grails-quartz'
}
----

===== 16.2 spring-context-support

The plugin builds its scheduler from `SchedulerFactoryBean` and its job factory from `AdaptableJobFactory`, both of which live in `org.springframework:spring-context-support`. Plugin version 4.0.x did not declare that dependency, and it is not reliably inherited from the rest of the stack, so an application failed at startup with:

[source]
----
java.lang.NoClassDefFoundError: org/springframework/scheduling/quartz/AdaptableJobFactory
----

until `spring-context-support` was added by hand. This affected any application using the standalone plugin releases, including one generated with the `grails-quartz` feature.

The dependency is now declared by the plugin and comes in transitively. If you added it explicitly as a workaround, it can be removed:

[source,groovy]
.build.gradle
----
dependencies {
    implementation 'org.apache.grails:grails-quartz'

    // no longer required -- provided transitively by grails-quartz
    // implementation 'org.springframework:spring-context-support'
}
----

===== 16.3 Job Class Properties

Job configuration properties such as `concurrent`, `sessionRequired`, `description`, and `group` must be declared as `static` rather than `def`. This changed in plugin version 2.0.13, so applications coming from an older release need to update their job classes:

[source,groovy]
----
class MyJob {

    // Grails 6 and earlier
    // def concurrent = false

    static concurrent = false

    static triggers = {
        simple repeatInterval: 5000L
    }

    void execute() {
        // ...
    }
}
----

See the xref:backgroundJobs.adoc#quartzJobProperties[Job Properties] section for the full set of supported properties and their defaults.
