diff --git a/grails-doc/src/en/guide/commandLine.adoc b/grails-doc/src/en/guide/commandLine.adoc index ee31e09eabb..b66755c6cd0 100644 --- a/grails-doc/src/en/guide/commandLine.adoc +++ b/grails-doc/src/en/guide/commandLine.adoc @@ -40,8 +40,8 @@ grails run-app It will first search the application, and then the profile for commands: * `PROJECT_HOME/src/main/scripts/run-app.groovy` -* `<>/commands/run-app.groovy` -* `<>/commands/run-app.yml` +* `<profile>/commands/run-app.groovy` +* `<profile>/commands/run-app.yml` To get a list of all commands and some help about the available commands type: diff --git a/grails-doc/src/en/guide/index.adoc b/grails-doc/src/en/guide/index.adoc index 2e7fa47e869..257c733c3bd 100644 --- a/grails-doc/src/en/guide/index.adoc +++ b/grails-doc/src/en/guide/index.adoc @@ -1075,11 +1075,6 @@ include::security/securityPlugins.adoc[] include::security/securityPlugins/springSecurity.adoc[] -[[shiro]] -==== Shiro - -include::security/securityPlugins/shiro.adoc[] - [[plugins]] == Plugins @@ -2542,4 +2537,3 @@ include::ref/Tags/uploadForm.adoc[] ==== while include::ref/Tags/while.adoc[] - diff --git a/grails-doc/src/en/guide/introduction/whatsNew.adoc b/grails-doc/src/en/guide/introduction/whatsNew.adoc index b0d4d9b49da..4e93ba0cd07 100644 --- a/grails-doc/src/en/guide/introduction/whatsNew.adoc +++ b/grails-doc/src/en/guide/introduction/whatsNew.adoc @@ -90,7 +90,7 @@ grails { } ---- -All three options are disabled by default and independent, or `compileStatic { all = true }` can be used as a shortcut to enable all of them. Any class that declares its own `@CompileDynamic` (or `@GrailsCompileStatic`/`@CompileStatic`/`@GrailsTypeChecked`/`@TypeChecked`) annotation keeps that setting, so the opt-in never overrides an explicit per-class choice. Tag libraries that still declare tags as closure fields (the deprecated form) are skipped automatically by the `tagLibs` opt-in — left dynamically compiled with a build warning — so define tags as methods to opt them in. See the xref:staticTypeCheckingAndCompilation/grailsCompileStatic[GrailsCompileStatic] section for details. +All three options are disabled by default and independent, or `compileStatic { all = true }` can be used as a shortcut to enable all of them. Any class that declares its own `@CompileDynamic` (or `@GrailsCompileStatic`/`@CompileStatic`/`@GrailsTypeChecked`/`@TypeChecked`) annotation keeps that setting, so the opt-in never overrides an explicit per-class choice. Tag libraries that still declare tags as closure fields (the deprecated form) are skipped automatically by the `tagLibs` opt-in and left dynamically compiled with a build warning, so define tags as methods to opt them in. See the link:staticTypeCheckingAndCompilation.html#grailsCompileStatic[GrailsCompileStatic] section for details. ==== Test HTTP Client Form Requests diff --git a/grails-doc/src/en/guide/links.yml b/grails-doc/src/en/guide/links.yml index 1a431fac484..35c9a022be3 100644 --- a/grails-doc/src/en/guide/links.yml +++ b/grails-doc/src/en/guide/links.yml @@ -136,8 +136,8 @@ logicAndIteration: 7.2.1.2 Logic and Iteration pageDirectives: 7.2.1.3 Page Directives expressions: 7.2.1.4 Expressions tags: 7.2.2 GSP Tags -variablesAndScopes: 7.2.2.1 Variables and Scopes -logicAndIteration: 7.2.2.2 Logic and Iteration +tagVariablesAndScopes: 7.2.2.1 Variables and Scopes +tagLogicAndIteration: 7.2.2.2 Logic and Iteration searchAndFiltering: 7.2.2.3 Search and Filtering linksAndResources: 7.2.2.4 Links and Resources formsAndFields: 7.2.2.5 Forms and Fields @@ -157,7 +157,7 @@ contentBlocks: 7.2.6 Content Blocks makingChangesToADeployedApplication: 7.2.7 Making Changes to a Deployed Application GSPDebugging: 7.2.8 GSP Debugging taglibs: 7.3 Tag Libraries -variablesAndScopes: 7.3.1 Variables and Scopes +taglibVariablesAndScopes: 7.3.1 Variables and Scopes simpleTags: 7.3.2 Simple Tags logicalTags: 7.3.3 Logical Tags iterativeTags: 7.3.4 Iterative Tags @@ -182,7 +182,7 @@ dataBindingAndValidation: 7.5.5 Data Binding and Validation filters: 7.6 Filters applyingFilters: 6.6.1 Applying Filters filterTypes: 6.6.2 Filter Types -variablesAndScopes: 6.6.3 Variables and Scopes +filterVariablesAndScopes: 6.6.3 Variables and Scopes filterDependencies: 6.6.4 Filter Dependencies ajax: 7.7 Ajax ajaxSupport: 7.7.1 Ajax Support @@ -236,7 +236,6 @@ codecs: 14.2 Encoding and Decoding Objects authentication: 14.3 Authentication securityPlugins: 14.4 Security Plug-ins springSecurity: 14.4.1 Spring Security -shiro: 14.4.2 Shiro plugins: 15. Plug-ins creatingAndInstallingPlugins: 15.1 Creating and Installing Plug-ins repositories: 15.2 Plugin Repositories diff --git a/grails-doc/src/en/guide/security/authentication.adoc b/grails-doc/src/en/guide/security/authentication.adoc index 57259499a4a..1a4d74b1554 100644 --- a/grails-doc/src/en/guide/security/authentication.adoc +++ b/grails-doc/src/en/guide/security/authentication.adoc @@ -17,7 +17,7 @@ specific language governing permissions and limitations under the License. //// -Grails has no default mechanism for authentication as it is possible to implement authentication in many different ways. It is however, easy to implement a simple authentication mechanism using link:theWebLayer.html#interceptors[interceptors]. This is sufficient for simple use cases but it's highly preferable to use an established security framework, for example by using the <> or the <> plugin. +Grails has no default mechanism for authentication as it is possible to implement authentication in many different ways. It is however, easy to implement a simple authentication mechanism using link:theWebLayer.html#interceptors[interceptors]. This is sufficient for simple use cases but it's highly preferable to use an established security framework, for example by using the link:security.html#springSecurity[Spring Security] plugin. Interceptors let you apply authentication across all controllers or across a URI space. For example you can create a new set of filters in a class called `grails-app/controllers/SecurityInterceptor.groovy` by running: diff --git a/grails-doc/src/en/guide/theWebLayer/fields/customizingFieldRendering.adoc b/grails-doc/src/en/guide/theWebLayer/fields/customizingFieldRendering.adoc index 666543c0354..72bc863ae95 100644 --- a/grails-doc/src/en/guide/theWebLayer/fields/customizingFieldRendering.adoc +++ b/grails-doc/src/en/guide/theWebLayer/fields/customizingFieldRendering.adoc @@ -296,7 +296,7 @@ NOTE: If the `bean` attribute was not supplied to `f:field` then `bean`, `type`, If the `label` attribute is not supplied to the `f:field` tag then the label string passed to the field template is resolved by convention. The plugin uses the following order of preference for the label: -* An i18n message using the key '_beanClass_._path_.label'. For example when using `` the plugin will try the i18n key `author.book.title.label`. If the property path contains any index it is removed so `` would use the key `author.books.title.label`. +* An i18n message using the key '_beanClass_._path_.label'. For example when using `` the plugin will try the i18n key `author.book.title.label`. If the property path contains any index it is removed so `` would use the key `author.books.title.label`. * For classes using the same bean class as properties, it is possible to get a key without the class name prefixed. If the configuration value `grails.plugin.fields.i18n.addPathFromRoot` is set to `true` (default: `false`). _Example_: a class `Publisher` has two `Address` properties `authorAddress` and `printAddress`. With `addPathFromRoot=true` they will share the key `address.city.label`. The same goes if `Author` and `Publisher` had a `Book book`, the key would be `book.title.label`, and if they both had a `List books` the key would be `books.title.label` * An i18n message using the key '_objectType_._propertyName_`.label`'. For example when using `` the plugin will try the i18n key `address.city.label`. * The natural property name. For example when using `` the plugin will use the label `"Date Of Birth"`. diff --git a/grails-doc/src/en/guide/theWebLayer/gson/gsonHal.adoc b/grails-doc/src/en/guide/theWebLayer/gson/gsonHal.adoc index 8f49837f889..c3cf4c1a99f 100644 --- a/grails-doc/src/en/guide/theWebLayer/gson/gsonHal.adoc +++ b/grails-doc/src/en/guide/theWebLayer/gson/gsonHal.adoc @@ -222,7 +222,7 @@ json { == Specifying the HAL Content Type -The default HAL response content type is `application/hal+json`, however as discussed in the section on link:#mime[TypesCustom Mime Type] you can define your own response content types to represent your resources. +The default HAL response content type is `application/hal+json`, however as discussed in the section on link:theWebLayer.html#mimeTypes[custom MIME types] you can define your own response content types to represent your resources. For example given the following configuration in `grails-app/conf/application.yml`: diff --git a/grails-doc/src/en/guide/upgrading/upgrading80x.adoc b/grails-doc/src/en/guide/upgrading/upgrading80x.adoc index c17cb0d63bc..2a3baf6edb1 100644 --- a/grails-doc/src/en/guide/upgrading/upgrading80x.adoc +++ b/grails-doc/src/en/guide/upgrading/upgrading80x.adoc @@ -359,7 +359,9 @@ grails: format: simple ---- -If you need to restore the legacy behavior temporarily, the deprecated marshallers remain available but will be removed in a future release. +The legacy `org.grails.web.converters.marshaller.json.EnumMarshaller` and `org.grails.web.converters.marshaller.xml.EnumMarshaller` classes were removed in Grails 8. +There is no Grails 8 configuration switch that restores the verbose enum-object shape. +If an external API contract still requires that shape, register a custom object marshaller explicitly. ==== 9. Jackson 3 is the New Default @@ -1346,3 +1348,77 @@ grails: - Presto - Trident ---- + +==== 31. Extension API Compatibility Notes + +Most Grails applications do not call the Grails extension APIs listed below directly. +They can affect applications, plugins, or build logic that import these public classes or override these public extension points directly. +Unsupported internal implementation details are not covered here. + +[cols="1,2,2", options="header"] +|=== +| Module +| Changed or removed API +| Migration note + +| `grails-codecs` +| `org.grails.plugins.codecs.CodecsGrailsPlugin` no longer overrides `doWithSpring()` +| Do not depend on that plugin override to contribute codec bean definitions. +Custom plugins should register their own beans from their own `doWithSpring()` implementation. + +| `grails-controllers` +| `ControllersAutoConfiguration.dispatcherServletRegistration(...)` now returns Spring Boot 4's `org.springframework.boot.webmvc.autoconfigure.DispatcherServletRegistrationBean` +| Update direct imports, overrides, and binary integrations that referenced the Spring Boot 3 return type. + +| `grails-converters` +| `grails.web.JSONBuilder` +| Use Groovy's `groovy.json.JsonBuilder` or `groovy.json.StreamingJsonBuilder` for JSON builder code. + +| `grails-core` +| `GrailsApplicationPostProcessor`, `ProfilingGrailsApplicationPostProcessor`, and `DefaultGrailsPluginManager` plugin-discovery wiring changed +| Update custom bootstrapping code or subclasses that construct `GrailsApplicationPostProcessor` or `DefaultGrailsPluginManager` directly to pass the plugin-discovery dependency. +`ProfilingGrailsApplicationPostProcessor` keeps its `GrailsApplicationLifeCycle`, `ApplicationContext`, and `Class...` constructor shape, but the application context must expose the `grailsPluginDiscovery` bean. +This was introduced during the Grails 7.1 plugin-loading changes and remains required in Grails 8. + +| `grails-core` +| `grails.plugins.PluginFilter`, `IncludingPluginFilter`, `ExcludingPluginFilter`, `NoOpPluginFilter`, and related filter types +| Import replacement types from the `org.apache.grails.core.plugins.filters` package, such as `PluginFilter`, `IncludingPluginFilter`, `ExcludingPluginFilter`, and `NoOpPluginFilter`. + +| `grails-core` +| Legacy mixin transform APIs such as `grails.util.Mixin`, `MixinTargetAware`, and `MixinTransformation` +| Replace legacy mixin usage with Groovy traits, extension methods, or explicit composition. + +| `grails-core` +| `grails.validation.ConstraintsEvaluator` +| Use `org.grails.datastore.gorm.validation.constraints.eval.ConstraintsEvaluator`. + +| `grails-core` +| `BinaryGrailsPluginDescriptor`, `CorePluginFinder`, and `BinaryGrailsPlugin.getBinaryDescriptor()` +| Use the current plugin-discovery APIs and `BinaryGrailsPlugin.getPluginDescriptor()`. + +| `grails-domain-class` +| `ConstraintEvaluatorAdapter` and `GrailsDomainClassAutoConfiguration.constraintsEvaluator(...)` +| Code that imported the auto-configuration method should use the current `validateableConstraintsEvaluator(...)` bean path and the datastore constraint evaluator APIs. + +| `grails-fields` +| `BeanPropertyAccessor.getBeanClass()`, its setter, `PropertyPathAccessor.getBeanClass()`, `FormFieldsTagLib.input(...)`, and direct `render*` helper methods +| Use the `beanType` property exposed by the accessors. +Custom field renderers should go through the documented `f:field`, `f:widget`, and `f:displayWidget` tags and templates instead of calling private render helpers directly. + +| `grails-gradle-plugins` +| `ApplicationContextCommandTask`, `ApplicationContextScriptTask`, `ProfileCompilerTask`, and `GrailsRunTask` are abstract; `GrailsGradlePlugin.createBuildPropertiesTask(...)` no longer returns a task value; several `IntegrationTestGradlePlugin` constants were removed +| Register these task types through Gradle task registration and update custom plugins that subclass `GrailsGradlePlugin` or read integration-test constants to use Gradle source sets, configurations, and the current test-phase APIs. + +| `grails-shell-cli` +| `AetherGrapeEngine` and `AetherGrapeEngineFactory` +| Use `MavenResolverGrapeEngine` and `MavenResolverGrapeEngineFactory` if you extend the legacy shell dependency resolver. + +| `grails-shell-cli` +| JLine 2 `complete(...)` signatures +| Implement the JLine 3 `org.jline.reader.Completer` contract, `complete(LineReader, ParsedLine, List)`. + +| `grails-spring` +| `GrailsApplicationContext.onRefresh()` +| Custom context subclasses should use supported Spring lifecycle extension points instead of overriding this removed hook. +Spring theme APIs removed from the same area are covered in section 10. +|===