You can build a Grails 8 application with Java 21, package it as a WAR, and deploy that archive to Open Liberty’s Servlet runtime. The workflow is straightforward; the exact Grails 8/Open Liberty pairing is not yet established by the official documentation reviewed. Grails documents WAR deployment to an external Servlet container, while Open Liberty documents WAR support and Servlet 5.0, 6.0, and 6.1 features. Treat the final container choice as a compatibility validation task, not as a guaranteed recipe.
What you need before creating the application
Use the current Grails 8 toolchain rather than instructions written for an older Grails release. The Grails 8.0.0 getting-started guide requires Java 21. Install a Java 21 JDK and make sure the same major version is visible to both the Grails build and the Open Liberty server that will run the WAR.
As an Amazon Associate I earn from qualifying purchases.
- Java: Java 21 is the documented Grails 8 requirement.
- Grails: Use a Grails 8 distribution and its CLI.
- Build system: Grails applications use Gradle. Generated projects contain a Gradle wrapper, so a separate system-wide Gradle installation is not required for the wrapper-based workflow.
- Container: Use an Open Liberty release whose documented Java and Servlet support matches the application you validate.
Check the JDK that your shell will use:
java -version
The output should identify Java 21. If your IDE, CI runner, or service manager selects another JDK, correcting only the interactive shell will not fix the deployment; check each environment separately.
Create a Grails 8 application
Generate the project with the CLI
From the directory in which you keep source code, run the Grails CLI’s create-app command:
grails create-app liberty-demo
cd liberty-demo
This creates a standard Grails application with source directories, configuration, Gradle build files, and wrapper scripts. The exact options available to create-app can vary with the selected Grails 8 distribution, so use grails help create-app if you need a non-default profile, package name, or feature set.
Use the generated Gradle wrapper
The project’s gradlew and gradlew.bat scripts bootstrap the Gradle version expected by that generated project. On Linux or macOS, make the Unix wrapper executable if necessary:
chmod +x gradlew
List the tasks exposed by the generated build before relying on a command copied from an older Grails article:
Free tools Windows power users keep installed
One-click scans. No signup required.
./gradlew tasks
On Windows, use gradlew.bat tasks. The wrapper is especially useful in CI because the project records the Gradle distribution it expects; developers do not have to coordinate a global Gradle version.
Run the application locally
Choose the command exposed by your Grails 8 project
Grails supports running an application through its CLI development lifecycle. A typical command is:
grails run-app
Some generated projects expose the equivalent development task through Gradle. Inspect ./gradlew tasks and the Grails 8 documentation for the distribution you installed, then use the task it actually generates rather than assuming that a task name from Grails 5, 6, or 7 still applies.
Rank #2
When the development server starts, note the port and context path printed by the application. Open the displayed local URL and exercise at least one controller route, a static asset, and any health or landing endpoint your application provides. This confirms that the project itself works before an external container is introduced.
Separate development behavior from container behavior
The local Grails run command is intended for development and may use an embedded server and development conveniences. Open Liberty is a separate runtime. A successful local run proves that the application builds and starts in its development mode; it does not prove that its WAR, Servlet API level, class-loader behavior, sessions, security constraints, or external resources work on Liberty.
Build the WAR that Open Liberty can deploy
Why WAR is the relevant artifact
For a traditional external Servlet container, package the application as a WAR. Grails also documents executable deployment as another option, but an executable application is not the artifact you deploy as a conventional Liberty web application. The Grails 8.0.0 deployment guide describes both deployment routes and states that the deployment host needs a compatible Java runtime but does not need Grails or Gradle installed.
Use the WAR command or generated Gradle task
The Grails 8 war command reference documents WAR creation. Depending on the selected Grails 8 distribution and generated build, the command surface may be the Grails CLI command or a Gradle task. First inspect the project:
./gradlew tasks
If the generated project exposes the standard Gradle WAR task, the invocation is commonly:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
./gradlew war
If the selected Grails distribution documents the CLI form, use:
grails war
Do not run both by assumption. Use the command documented for your exact Grails 8 distribution and confirm that it completes successfully. The resulting archive is normally placed under the build output directory, often build/libs; verify the actual path printed by the build rather than hard-coding a filename in deployment scripts.
Inspect the archive before deployment
Before copying the WAR to a server, check its contents and metadata:
- Confirm that the archive exists and has a non-zero size.
- Inspect
WEB-INF/web.xmlif present and review the application’s dependency metadata for the Servlet API namespace and version. - Check whether the application expects Jakarta Servlet classes or an older Java EE namespace. This affects which Liberty feature is appropriate.
- Confirm that configuration files, compiled classes, templates, static assets, and database drivers intended for runtime are included or supplied by the server.
- Record the WAR filename and the context path you intend to use; Liberty’s URL is determined by its application name and configuration.
Understand Open Liberty’s Servlet options
Open Liberty’s official feature references document WAR packaging and Servlet feature levels, including Jakarta Servlet 5.0, Jakarta Servlet 6.0, and Jakarta Servlet 6.1. Those references also list Java support, including Java 21 for the relevant current features. The documentation says that servlets can be packaged in Jakarta EE-specified WAR or EAR files.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →These facts establish that Liberty has the kind of WAR and Servlet runtime Grails needs in principle. They do not establish a tested Grails 8/Open Liberty release matrix. No reviewed primary source names a Liberty release, Servlet feature, and Grails 8 version as a verified combination. Select the feature only after checking the WAR’s actual Servlet/Jakarta expectations and the Liberty release you will operate.
Start with a minimal server configuration
Liberty features are enabled in server.xml. A conceptual configuration has a feature manager and an application entry, but the exact feature name and application configuration must match the Liberty release and the Servlet API level required by your WAR. Do not copy a Servlet 5.0, 6.0, or 6.1 choice into production merely because the number appears compatible.
Use the feature reference for your selected release to verify:
Rank #4
- the exact feature element name;
- the minimum and supported Java versions;
- which Jakarta EE or Servlet APIs it supplies;
- whether additional features are required by your application; and
- how the WAR is registered, whether through an application element or Liberty’s standard deployed-application directory.
Security constraints require an application security feature
The Liberty Servlet documentation warns that an application security feature must also be configured when Servlet security is required. Without a security feature, application security constraints are ignored. Therefore, if the Grails application declares protected URL patterns, authentication requirements, or role constraints, treat security as a separate Liberty configuration task and test it explicitly; a server that starts is not evidence that authorization is active.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Deploy the WAR to Open Liberty
- Choose and record versions. Write down the Grails 8 distribution, Java 21 vendor/version, Open Liberty release, selected Servlet feature, database driver version, and operating system.
- Build the archive. Run the verified Grails or Gradle WAR command from the project root and retain the build output.
- Configure the server. Enable the Servlet feature selected from Liberty’s reference documentation and add the WAR using Liberty’s normal application deployment mechanism for that server.
- Set runtime resources. Configure data sources, environment variables, credentials, logging, session settings, and any external services required by the application. Keep secrets outside source control.
- Start Liberty and read the messages. Examine the server log for feature resolution, application installation, class-loading errors, missing services, and context-path messages.
- Open the deployed URL. Use the context path reported by Liberty, then test an ordinary route before testing protected routes or database-backed pages.
Liberty can deploy applications through its standard server configuration and deployment layout. Because those details differ by Liberty installation and release, follow the deployment procedure shipped with your chosen Liberty runtime rather than assuming that a particular directory or command is universal.
Validate the Grails application on the chosen Liberty release
Validation is the step that turns a plausible WAR deployment into a supportable combination. Perform it on the same Liberty release and Servlet feature you plan to operate.
Startup and routing
- Confirm that the server reaches a started state without unresolved feature or class-loading errors.
- Verify the application context path and test representative Grails routes, including a route with path parameters if the application uses them.
- Check that redirects, URL generation, error pages, and status codes are correct when the application is not mounted at the root context.
Static files and views
- Load CSS, JavaScript, images, and other static assets from a clean browser session.
- Render representative server-side views and confirm that template resources are found after packaging.
- Check compression, cache headers, and any reverse-proxy path settings used in production.
Database and external services
- Exercise a read and a write against the configured database, if the application uses one.
- Verify connection-pool limits, transaction behavior, migrations, and startup handling when the database is temporarily unavailable.
- Test outbound calls with the same DNS, certificates, proxy, and firewall rules used by the production server.
Sessions, uploads, and security
- Log in, maintain a session across requests, log out, and verify timeout behavior.
- Test file uploads and downloads if the application supports them, including size limits and writable-directory permissions.
- Confirm that protected routes reject anonymous requests and allow only the intended roles. This specifically verifies that the required Liberty security feature is active.
Repeatability
Store the Liberty configuration and deployment instructions alongside the application, pin the Java and Liberty versions used in CI, and rebuild the WAR from a clean checkout. A deployment that works only after manual changes on one server is not yet a dependable Grails 8/Liberty integration.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Common failure modes and their fixes
The build uses the wrong Java version
Symptom: Gradle or Grails fails during startup, compilation, or dependency resolution with a Java-version error.
Fix: Check java -version in the shell, IDE, CI job, and Liberty service definition. Set all of them to a supported Java 21 JDK and rerun the wrapper build.
Best Value
The WAR builds but Liberty rejects it
Symptom: Liberty reports missing Servlet classes, incompatible namespaces, or application initialization errors.
Fix: Inspect the WAR’s descriptors and dependencies, then compare its Servlet/Jakarta expectations with the feature reference for the selected Liberty release. Try a feature level appropriate to the actual API contract only after documenting the change; the official pages do not supply a Grails 8-specific matrix.
The application starts but routes return 404
Symptom: Liberty reports a started application, but the browser cannot reach expected paths.
Fix: Check the deployed context path, the WAR filename/application name, proxy path rewriting, and whether the route is being requested with the correct leading context segment.
Security annotations appear to do nothing
Symptom: Requests that should be protected remain accessible.
Fix: Configure the Liberty application security feature required by the Servlet security model and define the relevant users, groups, or registry. The Servlet reference explicitly notes that constraints are ignored when no security feature is configured.
Database access works locally but fails on Liberty
Symptom: The development run connects, while the WAR deployment cannot obtain a connection.
Recommended Free Tools
Fix: Compare runtime configuration rather than application code: driver availability, JNDI or data-source names, credentials, network access, TLS certificates, and transaction settings. Confirm that the driver is packaged or supplied in the way your Liberty configuration expects.
What is and is not established about compatibility
| Question | What the official documentation establishes | What you must verify |
|---|---|---|
| Can Grails 8 create and build an application? | Yes. Grails 8 documentation describes project creation, Gradle-based builds, Java 21, development, and deployment. | The exact generated tasks and CLI options for your selected Grails 8 distribution. |
| Can Grails package a deployable WAR? | Yes. Grails documents WAR creation and deployment to an external Servlet container. | The output path, filename, and command exposed by your generated project. |
| Can Open Liberty run WAR files? | Yes. Liberty’s Servlet references document WAR packaging and Servlet feature support. | The correct Servlet feature, Liberty release, and any additional features for this WAR. |
| Is Grails 8 on Open Liberty officially tested? | Not established by the reviewed primary sources. | A real deployment test using the exact Grails, Java, Liberty, and feature versions you intend to support. |
The practical conclusion is narrow but useful: WAR packaging makes the approach reasonable, and Liberty supplies the relevant Servlet runtime capabilities, but only a versioned deployment test can establish that a particular Grails 8 application works correctly on a particular Open Liberty release.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

