Skip to content

Undertow Support for Grails 8 - #15985

Merged
jdaugherty merged 4 commits into
8.0.xfrom
feature/undertow
Jul 15, 2026
Merged

Undertow Support for Grails 8#15985
jdaugherty merged 4 commits into
8.0.xfrom
feature/undertow

Conversation

@jdaugherty

Copy link
Copy Markdown
Contributor

Description

Restores Undertow as an embedded servlet container option for Grails 8.

Spring Boot 4 removed its Undertow support (spring-boot-starter-undertow) before GA because
Undertow did not yet support Servlet 6.1, which Spring Boot 4 requires. Undertow has since shipped
Servlet 6.1 support (io.undertow:undertow-core 2.4.x plus the new io.undertow.ee servlet and
websockets artifacts). This PR brings that support back to Grails:

  • grails-undertow-spring-boot (grails-undertow/spring-boot): the spring-boot-undertow
    module vendored from Spring Boot 4.0.0-M1 (the last tag it existed in), repackaged as
    org.apache.grails.undertow.core and adapted to the Spring Boot 4.1 APIs. Spring Framework 7
    removed the reactive Undertow bridge classes (UndertowHttpHandlerAdapter et al.), so those are
    vendored from Spring Framework 6.2.19 and adapted. Per-file Spring license headers are retained,
    a module META-INF/NOTICE is included, the root NOTICE is updated, and the upstream source
    URLs are recorded in build.gradle (same approach as the vendored Spring ORM Hibernate 5 support).
  • grails-undertow (grails-undertow/plugin, package org.apache.grails.undertow.plugin):
    a Grails plugin that puts the vendored Undertow web server support and its dependencies on the
    application classpath, so switching containers is a single dependency:
    implementation 'org.apache.grails:grails-undertow'.
  • Grails Forge: the Undertow servlet feature is re-enabled and renamed grails-undertow
    (previously hidden and rejected with an error); --servlet=undertow works again and applies the
    new plugin. The fail-fast rejection in ContextFactory is removed.
  • BOM / dependency management: undertow.version (2.4.2.Final), undertow-servlet.version and
    undertow-websockets.version (2.0.1.Final, io.undertow.ee) are pinned in dependencies.gradle;
    both new modules are published and managed by grails-bom. Spring Boot 4 no longer manages
    Undertow, so these pins are required.
  • Security note: server.undertow.max-http-post-size defaults to 2MB, matching Undertow 2.4's
    hardened DEFAULT_MAX_ENTITY_SIZE (CVE-2024-3884, CVE-2024-4027). A non-positive value is still
    honored as an explicit opt-out to unlimited. This is called out in the upgrade notes.
  • Tests: the upstream self-contained tests are kept; tests that depended on unpublished Spring
    Boot test fixtures were rewritten as self-contained equivalents (server start/stop, SSL, access
    log, customizers, Spring MVC round-trip, autoconfiguration back-off). A new functional example app
    (grails-test-examples/undertow, mirroring the jetty example) verifies end-to-end that a Grails
    application boots on Undertow and serves a full request/redirect/session cycle, including an
    assertion that the running web server is the Undertow implementation.
  • Documentation: upgrade notes rewritten (migration snippet, post-size default), CLI reference
    pages updated for the renamed grails-undertow feature, and run-app documents the Undertow
    alternative.

Fixes #

Contributor Checklist

Issue and Scope

  • This PR is linked to an existing issue that has been acknowledged or approved by the project team.
  • This PR addresses the complete scope of the linked issue.
  • This PR contains a single, focused change.
  • This PR targets the correct branch for the type of change (new feature targeting the major release branch, 8.0.x).

Code Quality

  • I have added or updated tests that cover the changes introduced in this PR.
  • I have verified that all existing tests pass by running ./gradlew build --rerun-tasks.
  • My code follows the project's code style guidelines. I have run ./gradlew codeStyle and resolved any violations.
  • This PR does not include mass reformatting, style-only changes, or large-scale refactoring.
  • If generative AI tooling was used in preparing this contribution, a quality model was used to ensure contributions are consistent with the project's quality standards.

Licensing and Attribution

  • All contributed code is provided under the Apache License 2.0. New Grails source files carry the
    Apache license header; the vendored Spring Boot / Spring Framework sources retain their original
    Apache 2.0 license headers, with provenance documented in the module META-INF/NOTICE, the root
    NOTICE, and grails-undertow/spring-boot/build.gradle.
  • I have the necessary rights to submit this contribution.
  • If generative AI tooling was used in preparing this contribution, I have followed the ASF policy on generative tooling and have properly attributed its use.

Documentation

  • If this PR introduces user-facing changes, I have included or updated the relevant documentation.
  • If this PR adds a new feature, I have updated the What's New section of the Grails Guide.
  • If this PR introduces breaking changes or changes that require user action during an upgrade, I have updated the Upgrade Notes for the corresponding version in the Grails Guide (Undertow migration + the 2MB server.undertow.max-http-post-size default).
  • The PR description clearly explains what was changed and why.

@jdaugherty

Copy link
Copy Markdown
Contributor Author

Assuming all checks pass, we can activate this PR for review.

@jdaugherty

Copy link
Copy Markdown
Contributor Author

We may want to consider deprecating Undertow support, but in the mean time Grails 8 needs to support it.

This work was based on the suggestion in the upstream ticket where the Spring team suggested forking the modularised modules before they were removed: spring-projects/spring-boot#50381 (comment)

I'm re-adding this until the jboss-fuse fork is actually published. Once that is published, we can either eliminate the vendored files (adopt their fork) or deprecate the support in our preferred timeline.

@jdaugherty
jdaugherty marked this pull request as ready for review July 15, 2026 12:48
@testlens-app

testlens-app Bot commented Jul 15, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: 77723a6
▶️ Tests: 12089 executed
⚪️ Checks: 61/61 completed


Learn more about TestLens at testlens.app.

@jdaugherty jdaugherty added this to the grails:8.0.0-M4 milestone Jul 15, 2026
@jdaugherty
jdaugherty merged commit 532f94c into 8.0.x Jul 15, 2026
107 of 108 checks passed
@jdaugherty
jdaugherty deleted the feature/undertow branch July 15, 2026 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants