feat(jetty): configure Jetty server with custom settings and replace Tomcat dependencies#3028
feat(jetty): configure Jetty server with custom settings and replace Tomcat dependencies#3028balazs-szucs wants to merge 8 commits intobooklore-app:developfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR migrates the Booklore API embedded servlet container from Tomcat to Jetty to improve compatibility with special characters in query strings, and updates related configuration and error handling to match Jetty behavior.
Changes:
- Replaces Tomcat with Jetty in Gradle dependencies and updates
application.yamlwith Jetty server settings. - Adds a Jetty server customizer to relax URI parsing compliance for legacy query-string character support.
- Updates async exception handling to avoid Tomcat-specific exceptions; enables Caffeine cache stats recording.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
booklore-api/src/main/resources/application.yaml |
Removes Tomcat-specific settings; adds Jetty threads/timeout config and header-size setting. |
booklore-api/src/main/java/org/booklore/exception/GlobalExceptionHandler.java |
Replaces Tomcat ClientAbortException handling with IOException for broader Jetty compatibility. |
booklore-api/src/main/java/org/booklore/config/JettyConfig.java |
Adds Jetty URI compliance customization to allow legacy/special query characters. |
booklore-api/src/main/java/org/booklore/config/CacheConfig.java |
Enables Caffeine cache stats recording. |
booklore-api/build.gradle |
Excludes Tomcat starters and adds Jetty starter dependency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
booklore-api/src/main/java/org/booklore/exception/GlobalExceptionHandler.java
Show resolved
Hide resolved
booklore-api/src/main/java/org/booklore/config/JettyConfig.java
Outdated
Show resolved
Hide resolved
… test for legacy mode
…memory management
|
Hey, thanks for the PR! Just curious, what's the motivation for switching to Jetty? The special characters in query strings are already working fine with Tomcat's current config, so wondering if there's something else driving this. Want to make sure there's a clear reason before taking on a server swap since that touches a lot of stuff under the hood. |
|
Hi, see the motivation part of my pr message |
📝 Description
This pull request updates the Booklore API to switch the embedded servlet container from Tomcat to Jetty, ensuring compatibility with query parameters that use certain special characters. It also updates exception handling to work with the new server and adjusts related configuration files.
Linked Issue: Fixes #
🏷️ Type of Change
🔧 Changes
Switch to Jetty and related configuration:
spring-boot-starter-tomcatfrom thespring-boot-starter-webandspring-boot-starter-websocketdependencies, and addsspring-boot-starter-jettyinbuild.gradle.application.yamlto remove Tomcat-specific settings and add Jetty-specific thread and connection timeout configurations.Jetty URI compliance customization:
JettyConfig.javaconfiguration class to set Jetty'sUriCompliancetoLEGACY, allowing query-string characters such as[,],%,{,}, and|, matching the previous Tomcat relaxed query chars behavior.Exception handling adjustments:
GlobalExceptionHandler.javato handle client-aborted requests usingIOException(which is generic and compatible with Jetty) instead of the Tomcat-specificClientAbortException.Motivation
Migrating from Tomcat (Spring Boot's default) to Jetty provides several architectural and performance benefits:
Lower memory footprint: Jetty is highly modular and generally consumes less base memory than Tomcat. This is ideal for self-hosted setups (like small VPS instances, Raspberry Pis, or resource-constrained Docker containers) where minimizing overhead is a priority.
Faster startup times: Because of its streamlined architecture, Jetty typically boots faster than Tomcat, allowing for quicker deployments, restarts, and scaling.
Designed for embedding: While Tomcat can be embedded (as Spring Boot does by default), Jetty was designed from the ground up specifically to be an embedded web server. It plays exceptionally well inside standalone, self-contained applications.
Concurrency efficiency: Jetty's event-driven, asynchronous architecture handles a high number of concurrent connections highly efficiently without needing a massive thread pool (hence our tuned max: 200, min: 8 thread configuration).
🧪 Testing (MANDATORY)
Manual testing steps you performed:
Regression testing:
Edge cases covered:
Test output:
Backend test output (
./gradlew test)Frontend test output (
ng test)📸 Screen Recording / Screenshots (MANDATORY)
✅ Pre-Submission Checklist
develop(merge conflicts resolved)🤖 AI-Assisted Contributions
TODOs, or unused scaffolding left behind by AI💬 Additional Context (optional)
Startup logs: