If you’ve been writing Java for the web at any point in the last two decades, you’ve had to pick a web server or application server at least once. The choices haven’t changed much in name — Tomcat, JBoss, WildFly, and the relative newcomer Spring Boot are still the four most common answers — but the boundaries between them have. This post is a quick tour of each one and an honest table of when to reach for which. ☕
Servlet Container vs. Application Server
Before we get into the four contenders, one piece of vocabulary that trips people up. A servlet container implements the part of the Jakarta Enterprise Edition (Jakarta EE, formerly Java EE) specification that handles Hypertext Transfer Protocol (HTTP) requests, servlets, and JavaServer Pages (JSP). A full Jakarta EE application server implements that and the rest of the platform — Enterprise JavaBeans (EJB), Java Persistence Application Programming Interface (JPA), Java Message Service (JMS), Java Transaction API (JTA), Contexts and Dependency Injection (CDI), Java API for RESTful Web Services (JAX-RS), and so on.
Tomcat is a servlet container. JBoss Enterprise Application Platform (EAP) and WildFly are full Jakarta EE servers. Spring Boot is something different — it skips the container/server distinction entirely and ships an embedded server inside your application JAR. We’ll come back to that. 💡
Apache Tomcat
Tomcat is the original, the workhorse, the one that has been quietly running half the Java web in production since 1999. It’s developed under the Apache Software Foundation, implements the servlet, JSP, WebSocket, and Expression Language specs, and does not implement the heavier Jakarta EE pieces (no EJB, no JMS, no JTA out of the box).
That smaller surface area is its biggest feature. Tomcat starts in seconds, the configuration files (server.xml, web.xml) are short and well-understood, and the operational model is boring in the best sense — you drop a Web Application Archive (WAR) into webapps/ and a few seconds later the app is live.
1 2 3 4 5 | wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.18/bin/apache-tomcat-10.1.18.tar.gz tar xzf apache-tomcat-10.1.18.tar.gz cd apache-tomcat-10.1.18 cp ~/Downloads/my-app.war webapps/ ./bin/catalina.sh run |
If your app needs EJB or JMS, you’ll be wiring in Spring or Apache Camel or a standalone broker to fill those gaps. At which point you’re effectively building a half-application-server out of libraries — which is exactly the gap Spring Boot exists to close.
JBoss EAP
JBoss EAP is Red Hat’s commercial Jakarta EE application server. It’s the supported, certified, contractually-backed product version of WildFly. Same codebase, slower release cadence, security patches backported for years, paid support attached. You buy JBoss EAP when you have a procurement department that wants someone to sue if the server crashes at 2 a.m.
From a developer perspective, JBoss EAP is WildFly — the management console looks the same, the standalone.xml configuration looks the same, the deployment commands look the same. The difference is the support contract and the slower, hardened release line. 🛡️
WildFly
WildFly is the upstream open-source community version of JBoss EAP. It was renamed from JBoss Application Server in 2013 to make the distinction between the community product and the Red Hat product less confusing. (It mostly worked.) WildFly is fully compliant with Jakarta EE, supports MicroProfile out of the box for cloud-native APIs, and has a genuinely good administration story — the jboss-cli.sh tool can configure datasources, deploy WARs, change subsystem settings, and a hundred other things, scriptably.
1 2 | ./bin/standalone.sh -c standalone-full.xml ./bin/jboss-cli.sh --connect --command="deploy /path/to/my-app.war" |
If you actually need EJB, JMS via HornetQ/Artemis, distributed transactions, or the rest of the Jakarta EE stack, WildFly delivers all of it without you having to assemble it from libraries. The cost is startup time (tens of seconds, not single digits) and configuration surface area (standalone.xml is a thousand-plus lines on a fresh install).
Spring Boot
Spring Boot is the answer to the question: what if we just put the server inside the app? You write a main() method, the framework boots an embedded Tomcat (or Jetty, or Undertow) on a port, and your application starts handling requests. No external server to install, no WAR to deploy, no separate lifecycle to manage. You build a single executable JAR and run it like any other Java program.
1 2 3 4 5 6 | @SpringBootApplication public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); } } |
1 | java -jar my-app.jar |
This is the model that won the last decade. It fits perfectly with containers — one JAR, one process, one port, one health endpoint — and it removes an entire category of operational tickets (“why does our staging Tomcat have a different version than production?”). 🐳
Under the hood, Spring Boot defaults to embedded Tomcat. You can switch to embedded Jetty or Undertow by swapping a starter dependency. None of that changes your application code.
Side-by-Side Comparison
The honest summary:
| Aspect | Tomcat | JBoss EAP | WildFly | Spring Boot |
|---|---|---|---|---|
| Type | Servlet container | Jakarta EE app server (commercial) | Jakarta EE app server (community) | Embedded-server framework |
| License | Apache 2.0 | Commercial (Red Hat) | LGPL 2.1 | Apache 2.0 |
| Vendor | Apache Software Foundation | Red Hat / IBM | Red Hat / community | Broadcom / VMware Tanzu |
| Jakarta EE compliance | Web Profile only (Servlet, JSP, WebSocket, EL) | Full Platform | Full Platform + MicroProfile | Not certified; uses pieces via Spring |
| EJB / JMS / JTA | No (add libraries) | Yes | Yes | No (use Spring equivalents or libraries) |
| Deployment unit | WAR dropped into webapps/ | WAR / EAR via CLI or console | WAR / EAR via CLI or console | Executable JAR (or WAR if you must) |
| Startup time | Seconds | Tens of seconds | Tens of seconds | Seconds |
| Memory footprint | Light (~150 MB) | Heavy (500 MB+) | Heavy (500 MB+) | Light to moderate |
| Config style | server.xml, web.xml | standalone.xml, jboss-cli, web console | standalone.xml, jboss-cli, web console | application.properties / application.yml |
| Hot redeploy | Reload context | Yes, via CLI | Yes, via CLI | DevTools restart in dev |
| Container fit | Good | Workable, heavy | Workable, heavy | Excellent (one JAR, one process) |
| Commercial support | Third parties (Tomitribe, etc.) | Red Hat subscription | Community / Red Hat | Broadcom / Tanzu / third parties |
| Best fit | Simple servlet/JSP or Spring-based apps | Regulated enterprises needing certified Jakarta EE | Teams wanting full Jakarta EE without paying | New cloud-native services |
So Which Do You Pick?
For a new service in 2022 with no legacy constraints, Spring Boot is the default answer. You get the productivity of a modern framework, an embedded server that fits the container model, and an ecosystem that covers virtually every integration you’ll need. The friction is low and the talent pool is huge. 🎉
If you’re maintaining an existing Tomcat deployment, there’s rarely a reason to migrate just for the sake of it — Tomcat is still excellent at what it does, and a Spring application running inside a standalone Tomcat is a perfectly valid setup. The migration to Spring Boot’s embedded model is a refactor you do when it pays for itself, not a religious obligation.
JBoss EAP and WildFly remain the right answer when you genuinely need the Jakarta EE Full Platform — distributed transactions across multiple resources, message-driven EJBs, two-phase commit between a database and a JMS queue. If that sentence sounds like your domain, you already knew. If it doesn’t, you probably don’t need them.
Closing Thoughts
The boundary between “servlet container” and “application server” mattered a lot in 2005. Today, with Spring Boot doing most of what an app server used to do via libraries, and Jakarta EE app servers slimming down to compete (WildFly’s wildfly-jar-maven-plugin can build a single fat JAR these days), the four contenders overlap more than they diverge. Pick the one your team already knows, unless there’s a specific feature pulling you elsewhere. 🛠️
Further Reading
- Apache Tomcat documentation — tomcat.apache.org. Configuration reference for whichever Tomcat major version you’re running.
- WildFly documentation — docs.wildfly.org. Admin guide, model reference, and the jboss-cli tutorial.
- Red Hat JBoss EAP documentation — access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform. Production hardening, clustering, and the support matrix.
- Spring Boot reference documentation — docs.spring.io/spring-boot. The authoritative reference for the version you’re on.
- Jakarta EE specifications — jakarta.ee/specifications. The actual standards each of these servers claims to implement.